mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 00:51:24 +03:00
9ff8af5460
I tried to use 'systemctl --all list-units' to filter unit files, but this always filters out unit files which are not loaded. We want to complete systemctl start with those units too, so this approach is not going to work. New version is rather slow, but hopefully correct.
262 lines
11 KiB
Bash
262 lines
11 KiB
Bash
# systemctl(1) completion -*- shell-script -*-
|
|
#
|
|
# This file is part of systemd.
|
|
#
|
|
# Copyright 2010 Ran Benita
|
|
#
|
|
# systemd is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU Lesser General Public License as published by
|
|
# the Free Software Foundation; either version 2.1 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# systemd is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
__systemctl() {
|
|
local mode=$1; shift 1
|
|
systemctl $mode --full --no-legend "$@"
|
|
}
|
|
|
|
__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
|
|
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
|
|
}
|
|
|
|
__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_property $mode LoadState loaded $(
|
|
__filter_units_by_property $mode ActiveState inactive $(
|
|
__filter_units_by_property $mode CanStart yes $( __get_all_units )))
|
|
}
|
|
__get_restartable_units () {
|
|
# filter out masked and not-found
|
|
__filter_units_by_property $mode LoadState loaded $(
|
|
__filter_units_by_property $mode CanStart yes $( __get_all_units ))
|
|
}
|
|
__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; }; }
|
|
|
|
_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 --fail --ignore-dependencies --failed --force -f --full -l --global
|
|
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
|
|
--quiet -q --privileged -P --system --user --version --runtime --recursive -r'
|
|
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --root'
|
|
)
|
|
|
|
if __contains_word "--user" ${COMP_WORDS[*]}; then
|
|
mode=--user
|
|
else
|
|
mode=--system
|
|
fi
|
|
|
|
if __contains_word "$prev" ${OPTS[ARG]}; then
|
|
case $prev in
|
|
--signal|-s)
|
|
comps=$(compgen -A signal)
|
|
;;
|
|
--type|-t)
|
|
comps='automount busname device mount path service snapshot socket swap target timer'
|
|
;;
|
|
--state)
|
|
comps='loaded not-found stub
|
|
active inactive
|
|
dead elapsed exited listening mounted plugged running waiting'
|
|
;;
|
|
--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)
|
|
;;
|
|
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'
|
|
[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 reload-or-try-restart force-reload'
|
|
[RESTARTABLE_UNITS]='restart reload-or-restart'
|
|
[TARGET_AND_UNITS]='add-wants add-requires'
|
|
[MASKED_UNITS]='unmask'
|
|
[JOBS]='cancel'
|
|
[SNAPSHOTS]='delete'
|
|
[ENVS]='set-environment unset-environment'
|
|
[STANDALONE]='daemon-reexec daemon-reload default
|
|
emergency exit halt hibernate hybrid-sleep kexec list-jobs
|
|
list-sockets list-timers list-units list-unit-files poweroff
|
|
reboot rescue show-environment suspend get-default
|
|
is-system-running'
|
|
[NAME]='snapshot'
|
|
[FILE]='link'
|
|
[TARGETS]='set-default'
|
|
)
|
|
|
|
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]} ${VERBS[NAME]}; 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[SNAPSHOTS]}; then
|
|
comps=$( __systemctl $mode list-units --type snapshot --full --all \
|
|
| { 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
|