mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 16:59:03 +03:00
11a1589223
Files which are installed as-is (any .service and other unit files, .conf files, .policy files, etc), are left as is. My assumption is that SPDX identifiers are not yet that well known, so it's better to retain the extended header to avoid any doubt. I also kept any copyright lines. We can probably remove them, but it'd nice to obtain explicit acks from all involved authors before doing that.
303 lines
13 KiB
Bash
303 lines
13 KiB
Bash
# systemctl(1) completion -*- shell-script -*-
|
|
# SPDX-License-Identifier: LGPL-2.1+
|
|
#
|
|
# This file is part of systemd.
|
|
#
|
|
# Copyright 2010 Ran Benita
|
|
|
|
__systemctl() {
|
|
local mode=$1; shift 1
|
|
systemctl $mode --full --no-legend "$@" 2>/dev/null
|
|
}
|
|
|
|
__systemd_properties() {
|
|
local mode=$1
|
|
{ __systemctl $mode show --all;
|
|
@rootlibexecdir@/systemd --dump-configuration-items; } |
|
|
while IFS='=' read -r key value; do
|
|
[[ $value ]] && echo "$key"
|
|
done
|
|
}
|
|
|
|
__contains_word () {
|
|
local w word=$1; shift
|
|
for w in "$@"; do
|
|
[[ $w = "$word" ]] && return
|
|
done
|
|
}
|
|
|
|
__filter_units_by_property () {
|
|
local mode=$1 property=$2 value=$3 ; shift 3
|
|
local units=("$@")
|
|
local props i
|
|
IFS=$'\n' read -rd '' -a props < \
|
|
<(__systemctl $mode show --property "$property" -- "${units[@]}")
|
|
for ((i=0; $i < ${#units[*]}; i++)); do
|
|
if [[ "${props[i]}" = "$property=$value" ]]; then
|
|
echo " ${units[i]}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
__filter_units_by_properties () {
|
|
local mode=$1 properties=$2 values=$3 ; shift 3
|
|
local units=("$@")
|
|
local props i j conditions=()
|
|
IFS=$'\n' read -rd '' -a props < \
|
|
<(__systemctl $mode show --property "$properties" -- "${units[@]}")
|
|
IFS=$',' read -r -a properties < <(echo $properties)
|
|
IFS=$',' read -r -a values < <(echo $values)
|
|
for ((i=0; i < ${#properties[*]}; i++)); do
|
|
for ((j=0; j < ${#properties[*]}; j++)); do
|
|
if [[ ${props[i]%%=*} == ${properties[j]} ]]; then
|
|
conditions+=( "${properties[j]}=${values[j]}" )
|
|
fi
|
|
done
|
|
done
|
|
for ((i=0; i < ${#units[*]}; i++)); do
|
|
for ((j=0; j < ${#conditions[*]}; j++)); do
|
|
if [[ "${props[i * ${#conditions[*]} + j]}" != "${conditions[j]}" ]]; then
|
|
break
|
|
fi
|
|
done
|
|
if (( j == ${#conditions[*]} )); then
|
|
echo " ${units[i]}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
__get_all_units () { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \
|
|
| { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; }
|
|
__get_template_names () { __systemctl $1 list-unit-files \
|
|
| { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; }
|
|
|
|
__get_active_units () { __systemctl $1 list-units \
|
|
| { while read -r a b; do echo " $a"; done; }; }
|
|
__get_startable_units () {
|
|
# find startable inactive units
|
|
__filter_units_by_properties $1 ActiveState,CanStart inactive,yes $(
|
|
{ __systemctl $1 list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient | \
|
|
{ while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
|
|
__systemctl $1 list-units --state inactive,failed | \
|
|
{ while read -r a b c; do [[ $b == "loaded" ]] && echo " $a"; done; }
|
|
} | sort -u )
|
|
}
|
|
__get_restartable_units () {
|
|
# filter out masked and not-found
|
|
__filter_units_by_property $1 CanStart yes $(
|
|
__systemctl $1 list-unit-files --state enabled,disabled,static | \
|
|
{ while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
|
|
__systemctl $1 list-units | \
|
|
{ while read -r a b; do echo " $a"; done; } )
|
|
}
|
|
__get_failed_units () { __systemctl $1 list-units \
|
|
| { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; }
|
|
__get_enabled_units () { __systemctl $1 list-unit-files \
|
|
| { while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }; }
|
|
__get_disabled_units () { __systemctl $1 list-unit-files \
|
|
| { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; }
|
|
__get_masked_units () { __systemctl $1 list-unit-files \
|
|
| { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; }
|
|
__get_all_unit_files () { { __systemctl $1 list-unit-files; } | { while read -r a b; do echo " $a"; done; }; }
|
|
|
|
__get_machines() {
|
|
local a b
|
|
{ machinectl list-images --no-legend --no-pager; machinectl list --no-legend --no-pager; } | \
|
|
{ while read a b; do echo " $a"; done; }
|
|
}
|
|
|
|
_systemctl () {
|
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
|
local i verb comps mode
|
|
|
|
local -A OPTS=(
|
|
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
|
|
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
|
|
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup
|
|
--show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait'
|
|
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
|
|
--preset-mode -n --lines -o --output -M --machine --message'
|
|
)
|
|
|
|
if __contains_word "--user" ${COMP_WORDS[*]}; then
|
|
mode=--user
|
|
elif __contains_word "--global" ${COMP_WORDS[*]}; then
|
|
mode=--user
|
|
else
|
|
mode=--system
|
|
fi
|
|
|
|
if __contains_word "$prev" ${OPTS[ARG]}; then
|
|
case $prev in
|
|
--signal|-s)
|
|
_signals
|
|
return
|
|
;;
|
|
--type|-t)
|
|
comps=$(__systemctl $mode -t help)
|
|
;;
|
|
--state)
|
|
comps=$(__systemctl $mode --state=help)
|
|
;;
|
|
--job-mode)
|
|
comps='fail replace replace-irreversibly isolate
|
|
ignore-dependencies ignore-requirements flush'
|
|
;;
|
|
--kill-who)
|
|
comps='all control main'
|
|
;;
|
|
--root)
|
|
comps=$(compgen -A directory -- "$cur" )
|
|
compopt -o filenames
|
|
;;
|
|
--host|-H)
|
|
comps=$(compgen -A hostname)
|
|
;;
|
|
--property|-p)
|
|
comps=$(__systemd_properties $mode)
|
|
;;
|
|
--preset-mode)
|
|
comps='full enable-only disable-only'
|
|
;;
|
|
--output|-o)
|
|
comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json
|
|
json-pretty json-sse cat'
|
|
;;
|
|
--machine|-M)
|
|
comps=$( __get_machines )
|
|
;;
|
|
esac
|
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
|
return 0
|
|
fi
|
|
|
|
if [[ "$cur" = -* ]]; then
|
|
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
|
|
return 0
|
|
fi
|
|
|
|
local -A VERBS=(
|
|
[ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies edit set-property revert'
|
|
[ENABLED_UNITS]='disable'
|
|
[DISABLED_UNITS]='enable'
|
|
[REENABLABLE_UNITS]='reenable'
|
|
[FAILED_UNITS]='reset-failed'
|
|
[STARTABLE_UNITS]='start'
|
|
[STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
|
|
[ISOLATABLE_UNITS]='isolate'
|
|
[RELOADABLE_UNITS]='reload condreload try-reload-or-restart force-reload'
|
|
[RESTARTABLE_UNITS]='restart reload-or-restart'
|
|
[TARGET_AND_UNITS]='add-wants add-requires'
|
|
[MASKED_UNITS]='unmask'
|
|
[JOBS]='cancel'
|
|
[ENVS]='set-environment unset-environment import-environment'
|
|
[STANDALONE]='daemon-reexec daemon-reload default
|
|
emergency exit halt hibernate hybrid-sleep
|
|
suspend-then-hibernate kexec list-jobs list-sockets
|
|
list-timers list-units list-unit-files poweroff
|
|
reboot rescue show-environment suspend get-default
|
|
is-system-running preset-all'
|
|
[FILE]='link switch-root'
|
|
[TARGETS]='set-default'
|
|
[MACHINES]='list-machines'
|
|
)
|
|
|
|
for ((i=0; i < COMP_CWORD; i++)); do
|
|
if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
|
|
! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
|
|
verb=${COMP_WORDS[i]}
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ -z $verb ]]; then
|
|
comps="${VERBS[*]}"
|
|
|
|
elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
|
|
comps=$( __get_all_units $mode )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
|
|
comps=$( __get_enabled_units $mode )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
|
|
comps=$( __get_disabled_units $mode;
|
|
__get_template_names $mode)
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then
|
|
comps=$( __get_disabled_units $mode;
|
|
__get_enabled_units $mode;
|
|
__get_template_names $mode)
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
|
|
comps=$( __get_startable_units $mode;
|
|
__get_template_names $mode)
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
|
|
comps=$( __get_restartable_units $mode;
|
|
__get_template_names $mode)
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
|
|
comps=$( __filter_units_by_property $mode CanStop yes \
|
|
$( __get_active_units $mode ) )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
|
|
comps=$( __filter_units_by_property $mode CanReload yes \
|
|
$( __get_active_units $mode ) )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
|
|
comps=$( __filter_units_by_property $mode AllowIsolate yes \
|
|
$( __get_all_units $mode ) )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
|
|
comps=$( __get_failed_units $mode )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
|
|
comps=$( __get_masked_units $mode )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[TARGET_AND_UNITS]}; then
|
|
if __contains_word "$prev" ${VERBS[TARGET_AND_UNITS]} \
|
|
|| __contains_word "$prev" ${OPTS[STANDALONE]}; then
|
|
comps=$( __systemctl $mode list-unit-files --type target --all \
|
|
| { while read -r a b; do echo " $a"; done; } )
|
|
else
|
|
comps=$( __get_all_unit_files $mode )
|
|
fi
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
|
|
comps=''
|
|
|
|
elif __contains_word "$verb" ${VERBS[JOBS]}; then
|
|
comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } )
|
|
|
|
elif __contains_word "$verb" ${VERBS[ENVS]}; then
|
|
comps=$( __systemctl $mode show-environment \
|
|
| while read -r line; do echo " ${line%%=*}="; done )
|
|
compopt -o nospace
|
|
|
|
elif __contains_word "$verb" ${VERBS[FILE]}; then
|
|
comps=$( compgen -A file -- "$cur" )
|
|
compopt -o filenames
|
|
|
|
elif __contains_word "$verb" ${VERBS[TARGETS]}; then
|
|
comps=$( __systemctl $mode list-unit-files --type target --full --all \
|
|
| { while read -r a b; do echo " $a"; done; } )
|
|
fi
|
|
|
|
COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur") )
|
|
return 0
|
|
}
|
|
|
|
complete -F _systemctl systemctl
|