2013-03-03 01:34:01 +04:00
# systemctl(1) completion -*- shell-script -*-
2017-11-18 20:21:19 +03:00
# SPDX-License-Identifier: LGPL-2.1+
2013-03-03 01:34:01 +04:00
#
# This file is part of systemd.
#
2018-06-12 20:00:24 +03:00
# Copyright © 2010 Ran Benita
2013-03-03 01:34:01 +04:00
__systemctl() {
2013-04-05 15:45:30 +04:00
local mode=$1; shift 1
2018-04-30 14:37:29 +03:00
systemctl $mode --full --no-legend --no-pager "$@" 2>/dev/null
2013-03-03 01:34:01 +04:00
}
2013-04-17 04:38:41 +04:00
__systemd_properties() {
2018-05-28 08:19:16 +03:00
@rootlibexecdir@/systemd --dump-bus-properties
2013-04-17 04:38:41 +04:00
}
2013-03-03 01:34:01 +04:00
__contains_word () {
2013-07-30 20:46:23 +04:00
local w word=$1; shift
for w in "$@"; do
[[ $w = "$word" ]] && return
done
2013-03-03 01:34:01 +04:00
}
__filter_units_by_property () {
2013-04-05 15:45:30 +04:00
local mode=$1 property=$2 value=$3 ; shift 3
2013-03-03 01:34:01 +04:00
local units=("$@")
2016-09-14 09:22:45 +03:00
local props i
2013-03-03 01:34:01 +04:00
IFS=$'\n' read -rd '' -a props < \
2013-04-05 15:45:30 +04:00
<(__systemctl $mode show --property "$property" -- "${units[@]}")
2013-03-03 01:34:01 +04:00
for ((i=0; $i < ${#units[*]}; i++)); do
if [[ "${props[i]}" = "$property=$value" ]]; then
2013-04-11 03:06:00 +04:00
echo " ${units[i]}"
2013-03-03 01:34:01 +04:00
fi
done
}
2016-09-09 10:20:05 +03:00
__filter_units_by_properties () {
local mode=$1 properties=$2 values=$3 ; shift 3
local units=("$@")
2016-09-14 09:22:45 +03:00
local props i j conditions=()
2016-09-09 10:20:05 +03:00
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
2017-07-27 14:22:54 +03:00
if [[ "${props[i * ${#conditions[*]} + j]}" != "${conditions[j]}" ]]; then
2016-09-09 10:20:05 +03:00
break
fi
done
2016-09-14 09:22:45 +03:00
if (( j == ${#conditions[*]} )); then
2016-09-09 10:20:05 +03:00
echo " ${units[i]}"
fi
done
}
2018-06-07 18:24:45 +03:00
__get_all_units () { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \
2018-05-28 08:57:00 +03:00
| { while read -r a b; do echo " $a"; done; }; }
2018-06-07 18:24:45 +03:00
__get_non_template_units() { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \
2014-10-30 05:25:33 +03:00
| { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; }
2018-04-30 14:53:50 +03:00
__get_template_names () { __systemctl $1 list-unit-files "$2*" \
2014-10-15 05:10:02 +04:00
| { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; }
2018-04-30 14:53:50 +03:00
__get_active_units () { __systemctl $1 list-units "$2*" \
2013-04-11 03:06:00 +04:00
| { while read -r a b; do echo " $a"; done; }; }
2014-10-15 04:20:07 +04:00
__get_startable_units () {
2014-10-30 05:25:33 +03:00
# find startable inactive units
2017-07-27 14:22:54 +03:00
__filter_units_by_properties $1 ActiveState,CanStart inactive,yes $(
2018-04-30 14:53:50 +03:00
{ __systemctl $1 list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient "$2*" | \
2016-09-09 10:20:05 +03:00
{ while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
2018-04-30 14:53:50 +03:00
__systemctl $1 list-units --state inactive,failed "$2*" | \
2016-09-09 10:20:05 +03:00
{ while read -r a b c; do [[ $b == "loaded" ]] && echo " $a"; done; }
} | sort -u )
2014-10-30 05:25:33 +03:00
}
2014-10-15 04:20:07 +04:00
__get_restartable_units () {
2014-10-30 05:25:33 +03:00
# filter out masked and not-found
2017-07-27 14:22:54 +03:00
__filter_units_by_property $1 CanStart yes $(
2018-04-30 14:53:50 +03:00
__systemctl $1 list-unit-files --state enabled,disabled,static "$2*" | \
2014-10-30 06:06:58 +03:00
{ while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
2018-04-30 14:53:50 +03:00
__systemctl $1 list-units "$2*" | \
2014-10-30 06:06:58 +03:00
{ while read -r a b; do echo " $a"; done; } )
2014-10-30 05:25:33 +03:00
}
2018-04-30 14:53:50 +03:00
__get_failed_units () { __systemctl $1 list-units "$2*" \
2013-04-11 03:06:00 +04:00
| { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; }
2018-04-30 14:53:50 +03:00
__get_enabled_units () { __systemctl $1 list-unit-files "$2*" \
2013-04-11 03:06:00 +04:00
| { while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }; }
2018-04-30 14:53:50 +03:00
__get_disabled_units () { __systemctl $1 list-unit-files "$2*" \
2013-04-11 03:06:00 +04:00
| { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; }
2018-04-30 14:53:50 +03:00
__get_masked_units () { __systemctl $1 list-unit-files "$2*" \
2013-04-11 03:06:00 +04:00
| { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; }
2018-06-07 18:24:45 +03:00
__get_all_unit_files () { { __systemctl $1 list-unit-files "$2*"; } | { while read -r a b; do echo " $a"; done; }; }
2013-03-03 01:34:01 +04:00
2015-09-04 23:04:10 +03:00
__get_machines() {
local a b
2015-09-29 00:23:53 +03:00
{ machinectl list-images --no-legend --no-pager; machinectl list --no-legend --no-pager; } | \
{ while read a b; do echo " $a"; done; }
2015-09-04 23:04:10 +03:00
}
2013-03-03 01:34:01 +04:00
_systemctl () {
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
2013-04-05 15:45:30 +04:00
local i verb comps mode
2013-03-03 01:34:01 +04:00
local -A OPTS=(
2016-04-25 20:01:25 +03:00
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
2017-01-25 15:44:04 +03:00
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
2018-01-10 12:10:05 +03:00
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup
--show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait'
2015-09-04 23:04:10 +03:00
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
2018-01-10 12:10:05 +03:00
--preset-mode -n --lines -o --output -M --machine --message'
2013-03-03 01:34:01 +04:00
)
2013-04-17 04:38:41 +04:00
if __contains_word "--user" ${COMP_WORDS[*]}; then
mode=--user
2015-10-29 10:29:29 +03:00
elif __contains_word "--global" ${COMP_WORDS[*]}; then
mode=--user
2013-04-17 04:38:41 +04:00
else
mode=--system
fi
2013-03-03 01:34:01 +04:00
if __contains_word "$prev" ${OPTS[ARG]}; then
case $prev in
--signal|-s)
2015-11-24 19:05:42 +03:00
_signals
return
2013-03-03 01:34:01 +04:00
;;
--type|-t)
2015-08-14 00:54:58 +03:00
comps=$(__systemctl $mode -t help)
2013-03-03 01:34:01 +04:00
;;
2013-08-12 20:01:55 +04:00
--state)
2015-09-28 21:43:26 +03:00
comps=$(__systemctl $mode --state=help)
2013-08-12 20:01:55 +04:00
;;
2015-05-18 07:58:24 +03:00
--job-mode)
comps='fail replace replace-irreversibly isolate
ignore-dependencies ignore-requirements flush'
;;
2013-03-03 01:34:01 +04:00
--kill-who)
comps='all control main'
;;
--root)
comps=$(compgen -A directory -- "$cur" )
compopt -o filenames
;;
--host|-H)
comps=$(compgen -A hostname)
;;
--property|-p)
2018-05-28 08:19:16 +03:00
comps=$(__systemd_properties)
2013-03-03 01:34:01 +04:00
;;
2015-09-04 23:04:10 +03:00
--preset-mode)
comps='full enable-only disable-only'
;;
--output|-o)
2017-05-08 03:23:49 +03:00
comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json
2015-09-04 23:04:10 +03:00
json-pretty json-sse cat'
;;
--machine|-M)
comps=$( __get_machines )
;;
2013-03-03 01:34:01 +04:00
esac
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
return 0
fi
if [[ "$cur" = -* ]]; then
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
return 0
fi
local -A VERBS=(
2018-05-28 08:57:00 +03:00
[ALL_UNITS]='cat mask'
[NONTEMPLATE_UNITS]='is-active is-failed is-enabled status show preset help list-dependencies edit set-property revert'
2013-04-11 03:31:58 +04:00
[ENABLED_UNITS]='disable'
2013-03-03 01:34:01 +04:00
[DISABLED_UNITS]='enable'
2013-04-11 03:31:58 +04:00
[REENABLABLE_UNITS]='reenable'
2013-03-03 01:34:01 +04:00
[FAILED_UNITS]='reset-failed'
[STARTABLE_UNITS]='start'
[STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
[ISOLATABLE_UNITS]='isolate'
2016-01-28 20:57:04 +03:00
[RELOADABLE_UNITS]='reload condreload try-reload-or-restart force-reload'
2013-03-03 01:34:01 +04:00
[RESTARTABLE_UNITS]='restart reload-or-restart'
2014-10-16 11:41:02 +04:00
[TARGET_AND_UNITS]='add-wants add-requires'
2013-03-03 01:34:01 +04:00
[MASKED_UNITS]='unmask'
[JOBS]='cancel'
2018-01-10 12:10:05 +03:00
[ENVS]='set-environment unset-environment import-environment'
2013-10-22 02:53:57 +04:00
[STANDALONE]='daemon-reexec daemon-reload default
2018-03-08 16:17:33 +03:00
emergency exit halt hibernate hybrid-sleep
2018-03-28 19:00:06 +03:00
suspend-then-hibernate kexec list-jobs list-sockets
2018-03-08 16:17:33 +03:00
list-timers list-units list-unit-files poweroff
2014-10-28 05:34:28 +03:00
reboot rescue show-environment suspend get-default
2018-01-10 12:10:05 +03:00
is-system-running preset-all'
2015-04-03 05:54:35 +03:00
[FILE]='link switch-root'
2013-05-28 13:05:48 +04:00
[TARGETS]='set-default'
2018-01-10 12:10:05 +03:00
[MACHINES]='list-machines'
2013-03-03 01:34:01 +04:00
)
2014-02-06 09:31:22 +04:00
for ((i=0; i < COMP_CWORD; i++)); do
2013-03-03 01:34:01 +04:00
if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
verb=${COMP_WORDS[i]}
break
fi
done
2013-12-06 06:33:08 +04:00
if [[ -z $verb ]]; then
2013-03-03 01:34:01 +04:00
comps="${VERBS[*]}"
elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
2018-06-07 18:24:45 +03:00
comps=$( __get_all_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
2018-05-28 08:57:00 +03:00
elif __contains_word "$verb" ${VERBS[NONTEMPLATE_UNITS]}; then
2018-06-07 18:24:45 +03:00
comps=$( __get_non_template_units $mode "$cur" )
2018-05-28 08:57:00 +03:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
2018-04-30 14:53:50 +03:00
comps=$( __get_enabled_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
2018-04-30 14:53:50 +03:00
comps=$( __get_disabled_units $mode "$cur";
__get_template_names $mode "$cur")
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
2013-04-11 03:31:58 +04:00
elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then
2018-04-30 14:53:50 +03:00
comps=$( __get_disabled_units $mode "$cur";
__get_enabled_units $mode "$cur";
__get_template_names $mode "$cur")
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-04-11 03:31:58 +04:00
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
2018-06-11 18:35:23 +03:00
comps=$( __get_startable_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
2018-06-11 18:35:23 +03:00
comps=$( __get_restartable_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
2013-04-05 15:45:30 +04:00
comps=$( __filter_units_by_property $mode CanStop yes \
2018-04-30 14:53:50 +03:00
$( __get_active_units $mode "$cur" ) )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
2013-04-05 15:45:30 +04:00
comps=$( __filter_units_by_property $mode CanReload yes \
2018-04-30 14:53:50 +03:00
$( __get_active_units $mode "$cur" ) )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
2013-04-05 15:45:30 +04:00
comps=$( __filter_units_by_property $mode AllowIsolate yes \
2018-06-07 18:24:45 +03:00
$( __get_all_units $mode "$cur" ) )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
2018-04-30 14:53:50 +03:00
comps=$( __get_failed_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
2018-04-30 14:53:50 +03:00
comps=$( __get_masked_units $mode "$cur" )
2014-07-27 23:07:03 +04:00
compopt -o filenames
2013-03-03 01:34:01 +04:00
2014-10-16 11:41:02 +04:00
elif __contains_word "$verb" ${VERBS[TARGET_AND_UNITS]}; then
if __contains_word "$prev" ${VERBS[TARGET_AND_UNITS]} \
|| __contains_word "$prev" ${OPTS[STANDALONE]}; then
2018-06-07 18:24:45 +03:00
comps=$( __systemctl $mode list-unit-files --type target --all "$cur*" \
2014-10-16 11:41:02 +04:00
| { while read -r a b; do echo " $a"; done; } )
else
2018-06-07 18:24:45 +03:00
comps=$( __get_all_unit_files $mode "$cur" )
2014-10-16 11:41:02 +04:00
fi
compopt -o filenames
Remove snapshot unit type
Snapshots were never useful or used for anything. Many systemd
developers that I spoke to at systemd.conf2015, didn't even know they
existed, so it is fairly safe to assume that this type can be deleted
without harm.
The fundamental problem with snapshots is that the state of the system
is dynamic, devices come and go, users log in and out, timers fire...
and restoring all units to some state from the past would "undo"
those changes, which isn't really possible.
Tested by creating a snapshot, running the new binary, and checking
that the transition did not cause errors, and the snapshot is gone,
and snapshots cannot be created anymore.
New systemctl says:
Unknown operation snapshot.
Old systemctl says:
Failed to create snapshot: Support for snapshots has been removed.
IgnoreOnSnaphost settings are warned about and ignored:
Support for option IgnoreOnSnapshot= has been removed and it is ignored
http://lists.freedesktop.org/archives/systemd-devel/2015-November/034872.html
2015-11-08 16:12:54 +03:00
elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
2013-03-03 01:34:01 +04:00
comps=''
elif __contains_word "$verb" ${VERBS[JOBS]}; then
2013-04-11 03:06:00 +04:00
comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } )
2013-03-03 01:34:01 +04:00
elif __contains_word "$verb" ${VERBS[ENVS]}; then
2013-04-05 15:45:30 +04:00
comps=$( __systemctl $mode show-environment \
2018-01-10 12:10:05 +03:00
| while read -r line; do echo " ${line%%=*}="; done )
2013-03-03 01:34:01 +04:00
compopt -o nospace
elif __contains_word "$verb" ${VERBS[FILE]}; then
comps=$( compgen -A file -- "$cur" )
compopt -o filenames
2018-01-10 12:10:05 +03:00
2013-05-28 13:05:48 +04:00
elif __contains_word "$verb" ${VERBS[TARGETS]}; then
2018-06-07 18:24:45 +03:00
comps=$( __systemctl $mode list-unit-files --type target --full --all "$cur*" \
2013-05-28 13:05:48 +04:00
| { while read -r a b; do echo " $a"; done; } )
2013-03-03 01:34:01 +04:00
fi
2014-07-27 23:07:03 +04:00
COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur") )
2013-03-03 01:34:01 +04:00
return 0
}
complete -F _systemctl systemctl