summaryrefslogtreecommitdiffstats
path: root/shell-completion/bash
diff options
context:
space:
mode:
Diffstat (limited to 'shell-completion/bash')
-rw-r--r--shell-completion/bash/bootctl109
-rw-r--r--shell-completion/bash/busctl208
-rw-r--r--shell-completion/bash/coredumpctl97
-rw-r--r--shell-completion/bash/homectl191
-rw-r--r--shell-completion/bash/hostnamectl92
-rw-r--r--shell-completion/bash/journalctl154
-rw-r--r--shell-completion/bash/kernel-install48
-rw-r--r--shell-completion/bash/localectl96
-rw-r--r--shell-completion/bash/loginctl125
-rw-r--r--shell-completion/bash/machinectl117
-rw-r--r--shell-completion/bash/meson.build57
-rw-r--r--shell-completion/bash/networkctl84
-rw-r--r--shell-completion/bash/oomctl57
-rw-r--r--shell-completion/bash/portablectl116
-rw-r--r--shell-completion/bash/resolvectl204
-rw-r--r--shell-completion/bash/systemctl.in406
-rw-r--r--shell-completion/bash/systemd-analyze207
-rw-r--r--shell-completion/bash/systemd-cat57
-rw-r--r--shell-completion/bash/systemd-cgls71
-rw-r--r--shell-completion/bash/systemd-cgtop68
-rw-r--r--shell-completion/bash/systemd-confext85
-rw-r--r--shell-completion/bash/systemd-cryptenroll117
-rw-r--r--shell-completion/bash/systemd-delta60
-rw-r--r--shell-completion/bash/systemd-detect-virt40
-rw-r--r--shell-completion/bash/systemd-dissect127
-rw-r--r--shell-completion/bash/systemd-id12874
-rw-r--r--shell-completion/bash/systemd-nspawn200
-rw-r--r--shell-completion/bash/systemd-path61
-rw-r--r--shell-completion/bash/systemd-resolve80
-rw-r--r--shell-completion/bash/systemd-run132
-rw-r--r--shell-completion/bash/systemd-sysext85
-rw-r--r--shell-completion/bash/timedatectl97
-rw-r--r--shell-completion/bash/udevadm322
33 files changed, 4044 insertions, 0 deletions
diff --git a/shell-completion/bash/bootctl b/shell-completion/bash/bootctl
new file mode 100644
index 0000000..8d8b507
--- /dev/null
+++ b/shell-completion/bash/bootctl
@@ -0,0 +1,109 @@
+# bootctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_entry_ids() {
+ bootctl --no-pager list 2>/dev/null | { while read -r a b; do [[ $a == 'id:' ]] && echo " $b"; done }
+}
+
+_bootctl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful --dry-run'
+ [ARG]='--esp-path --boot-path --make-machine-id-directory --root --image --install-source'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --esp-path|--boot-path)
+ if [[ -z $cur ]]; then
+ comps=$(compgen -A directory -- "/" )
+ else
+ comps=$(compgen -A directory -- "$cur" )
+ fi
+ compopt -o filenames
+ ;;
+ --make-machine-id-directory)
+ comps="yes no auto"
+ ;;
+ --image|--root)
+ compopt -o nospace
+ comps=$( compgen -A file -- "$cur" )
+ ;;
+ --install-source)
+ comps="image host auto"
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ # systemd-efi-options takes an argument, but it is free-form, so we cannot complete it
+ [STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list set-timeout set-timeout-oneshot cleanup'
+ [BOOTENTRY]='set-default set-oneshot unlink'
+ [BOOLEAN]='reboot-to-firmware'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[BOOTENTRY]}; then
+ name=
+ for ((i++; i < COMP_CWORD; i++)); do
+ if ! __contains_word "${COMP_WORDS[i]}" ${OPTS[*]} ${VERBS[*]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps=$( __get_entry_ids )
+ else
+ comps=''
+ fi
+ elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
+ comps="yes no"
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _bootctl bootctl
diff --git a/shell-completion/bash/busctl b/shell-completion/bash/busctl
new file mode 100644
index 0000000..5464225
--- /dev/null
+++ b/shell-completion/bash/busctl
@@ -0,0 +1,208 @@
+# busctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__get_busnames() {
+ local mode=$1
+ local a b
+ busctl $mode list --no-legend --no-pager --full 2>/dev/null |
+ { while read a b; do echo " $a"; done; };
+}
+
+__get_objects() {
+ local mode=$1
+ local busname=$2
+ local a b
+ busctl $mode tree --list --no-legend --no-pager $busname 2>/dev/null |
+ { while read a b; do echo " $a"; done; };
+}
+
+__get_interfaces() {
+ local mode=$1
+ local busname=$2
+ local path=$3
+ local a b c
+ busctl $mode introspect --list --no-legend --no-pager $busname $path 2>/dev/null |
+ { while read a b c; do [[ "$b" == "interface" ]] && echo " $a"; done; };
+}
+
+__get_members() {
+ local mode=$1
+ local busname=$2
+ local path=$3
+ local interface=$4
+ local type=$5
+ local flags=$6
+ local a b c d e
+ busctl $mode introspect --list --no-legend --no-pager $busname $path $interface 2>/dev/null |
+ sed -e 's/^\.//' |
+ { while read a b c d e; do [[ "$b" == "$type" && ( -z $flags || "$e" == "$flags" ) ]] && echo " $a"; done; };
+}
+
+__get_signature() {
+ local mode=$1
+ local busname=$2
+ local path=$3
+ local interface=$4
+ local member=$5
+ local a b c d
+ busctl $mode introspect --list --no-legend --no-pager $busname $path $interface 2>/dev/null |
+ sed -e 's/^\.//' | { while read a b c d; do [[ "$a" == "$member" && "$c" != '-' ]] && echo " \"$c\""; done; };
+}
+
+_busctl() {
+ local i n verb comps mode
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --no-pager --no-legend --system --user
+ --show-machine --unique --acquired --activatable --list
+ -q --quiet --verbose --expect-reply=no --auto-start=no
+ --allow-interactive-authorization=no --augment-creds=no
+ --watch-bind=yes -j -l --full --xml-interface'
+ [ARG]='--address -H --host -M --machine --match --timeout --size --json
+ --destination'
+ )
+
+ if __contains_word "--user" ${COMP_WORDS[*]}; then
+ mode=--user
+ else
+ mode=--system
+ fi
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --json)
+ comps=$( busctl --json=help 2>/dev/null )
+ ;;
+ --destination)
+ comps=$( __get_busnames $mode )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [STANDALONE]='list help'
+ [BUSNAME]='status monitor capture tree'
+ [OBJECT]='introspect'
+ [METHOD]='call'
+ [EMIT]='emit'
+ [PROPERTY_GET]='get-property'
+ [PROPERTY_SET]='set-property'
+ )
+
+ 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
+
+ n=$((COMP_CWORD - i))
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[BUSNAME]}; then
+ comps=$( __get_busnames $mode)
+ elif __contains_word "$verb" ${VERBS[OBJECT]}; then
+ if [[ $n -eq 1 ]] ; then
+ comps=$( __get_busnames $mode)
+ elif [[ $n -eq 2 ]] ; then
+ comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 3 ]] ; then
+ comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ else
+ comps=''
+ fi
+ elif __contains_word "$verb" ${VERBS[METHOD]}; then
+ if [[ $n -eq 1 ]] ; then
+ comps=$( __get_busnames $mode)
+ elif [[ $n -eq 2 ]] ; then
+ comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 3 ]] ; then
+ comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 4 ]] ; then
+ comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} method)
+ elif [[ $n -eq 5 ]] ; then
+ comps=$( __get_signature $mode ${COMP_WORDS[COMP_CWORD-4]} ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ else
+ comps=''
+ fi
+ elif __contains_word "$verb" ${VERBS[EMIT]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[PROPERTY_GET]}; then
+ if [[ $n -eq 1 ]] ; then
+ comps=$( __get_busnames $mode)
+ elif [[ $n -eq 2 ]] ; then
+ comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 3 ]] ; then
+ comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 4 ]] ; then
+ comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} property)
+ else
+ comps=''
+ fi
+ elif __contains_word "$verb" ${VERBS[PROPERTY_SET]}; then
+ if [[ $n -eq 1 ]] ; then
+ comps=$( __get_busnames $mode)
+ elif [[ $n -eq 2 ]] ; then
+ comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 3 ]] ; then
+ comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ elif [[ $n -eq 4 ]] ; then
+ comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} property writable)
+ elif [[ $n -eq 5 ]] ; then
+ comps=$( __get_signature $mode ${COMP_WORDS[COMP_CWORD-4]} ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+ else
+ comps=''
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _busctl busctl
diff --git a/shell-completion/bash/coredumpctl b/shell-completion/bash/coredumpctl
new file mode 100644
index 0000000..b571990
--- /dev/null
+++ b/shell-completion/bash/coredumpctl
@@ -0,0 +1,97 @@
+# coredumpctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
+ ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
+ _{P,U,G}ID _COMM _EXE _CMDLINE
+ _AUDIT_{SESSION,LOGINUID}
+ _SYSTEMD_{CGROUP,SESSION,UNIT,OWNER_UID}
+ _SELINUX_CONTEXT _SOURCE_REALTIME_TIMESTAMP
+ _{BOOT,MACHINE}_ID _HOSTNAME _TRANSPORT
+ _KERNEL_{DEVICE,SUBSYSTEM}
+ _UDEV_{SYSNAME,DEVNODE,DEVLINK}
+ __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
+_coredumpctl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1
+ -r --reverse -S --since -U --until -D --directory -q --quiet --debugger
+ -A --debugger-arguments --json -n --all --file --root --image'
+
+ local -A VERBS=(
+ [LIST]='list info'
+ [DUMP]='dump debug'
+ )
+
+ if __contains_word "$prev" --output -o --file --image; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ elif __contains_word "$prev" -D --directory --root; then
+ comps=$( compgen -A directory -- "$cur" )
+ compopt -o filenames
+ elif __contains_word "$prev" '--debugger'; then
+ comps=$( compgen -A command -- "$cur" )
+ compopt -o filenames
+ elif __contains_word "$prev" --field -F; then
+ comps=$( compgen -W '${__journal_fields[*]}' -- "$cur" )
+ elif __contains_word "$prev" '--json'; then
+ comps=$( compgen -W 'pretty short off' -- "$cur" )
+ elif [[ $cur = -* ]]; then
+ comps=${OPTS}
+ elif __contains_word "$prev" ${VERBS[*]} &&
+ ! __contains_word ${COMP_WORDS[COMP_CWORD-2]} \
+ '--output -o -D --directory -F --field --debugger'; then
+ compopt -o nospace
+ COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
+ return 0
+ elif [[ $cur = *=* ]]; then
+ mapfile -t field_vals < <(coredumpctl -F "${prev%=}" 2>/dev/null)
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+ return 0
+ elif [[ $prev = '=' ]]; then
+ mapfile -t field_vals < <(coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+ comps=${field_vals[*]}
+ else
+ for ((i=0; i <= COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[LIST]} ${VERBS[DUMP]}; then
+ comps=''
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _coredumpctl coredumpctl
diff --git a/shell-completion/bash/homectl b/shell-completion/bash/homectl
new file mode 100644
index 0000000..0a7bd0d
--- /dev/null
+++ b/shell-completion/bash/homectl
@@ -0,0 +1,191 @@
+# homectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ machinectl list --full --no-legend --no-pager 2>/dev/null |
+ { while read a b; do echo " $a"; done; };
+}
+
+__get_homes() {
+ homectl --no-pager --no-legend list 2>/dev/null
+}
+
+_homectl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version
+ --no-pager --no-legend --no-ask-password
+ -j -E -P'
+ [ARG]=' -H --host
+ -M --machine
+ --identity
+ --json
+ --export-format
+ -c --real-name
+ --realm
+ --email-address
+ --location
+ --icon-name
+ -d --home-dir
+ --uid
+ -G --member-of
+ --skel
+ --shell
+ --setenv
+ --timezone
+ --language
+ --ssh-authorized-keys
+ --pkcs11-token-uri
+ --locked
+ --not-before
+ --not-after
+ --rate-limit-interval
+ --rate-limit-burst
+ --password-hint
+ --enforce-password-policy
+ --password-change-now
+ --password-change-min
+ --password-change-max
+ --password-change-warn
+ --password-change-inactive
+ --disk-size
+ --access-mode
+ --umask
+ --nice
+ --rlimit
+ --tasks-max
+ --memory-high
+ --memory-max
+ --cpu-weight
+ --io-weight
+ --storage
+ --image-path
+ --fs-type
+ --luks-discard
+ --luks-offline-discard
+ --luks-cipher
+ --luks-cipher-mode
+ --luks-volume-key-size
+ --luks-pbkdf-type
+ --luks-pbkdf-hash-algorithm
+ --luks-pbkdf-force-iterations
+ --luks-pbkdf-time-cost
+ --luks-pbkdf-memory-cost
+ --luks-pbkdf-parallel-threads
+ --luks-sector-size
+ --nosuid
+ --nodev
+ --noexec
+ --cifs-domain
+ --cifs-user-name
+ --cifs-service
+ --stop-delay
+ --kill-processes
+ --auto-login'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --identity|--image-path)
+ comps=$(compgen -A file -- "$cur" )
+ compopt -o filenames
+ ;;
+ --json)
+ comps='pretty short off'
+ ;;
+ --export-format)
+ comps='full stripped minimal'
+ ;;
+ --locked|--enforce-password-policy|--password-change-now|--luks-discard|--luks-offline-discard|--nosuid|--nodev|--noexec|--kill-processes|--auto-login)
+ comps='yes no'
+ ;;
+ -d|--home-dir|--skel)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o dirnames
+ ;;
+ -G|--member-of)
+ comps=$(compgen -A group -- "$cur" )
+ ;;
+ --shell)
+ comps=$(cat /etc/shells)
+ ;;
+ --fs-type)
+ comps='btrfs ext4 xfs'
+ ;;
+ --cifs-user-name)
+ comps=$(compgen -A user -- "$cur" )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [STANDALONE]='list lock-all'
+ [CREATE]='create'
+ [NAMES]='activate deactivate inspect authenticate remove lock unlock'
+ [NAME]='update passwd'
+ [RESIZE]='resize'
+ [WITH]='with'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[NAME]}; then
+ comps=$(__get_homes)
+ elif __contains_word "$verb" ${VERBS[NAMES]}; then
+ comps=$(__get_homes)
+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[CREATE]} ${VERBS[RESIZE]}; then
+ comps=$(__get_homes)
+ elif __contains_word "$verb" ${VERBS[WITH]}; then
+ comps=$(__get_homes)
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _homectl homectl
diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl
new file mode 100644
index 0000000..63edc08
--- /dev/null
+++ b/shell-completion/bash/hostnamectl
@@ -0,0 +1,92 @@
+# hostnamectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ machinectl list --full --no-legend --no-pager 2>/dev/null |
+ { while read a b; do echo " $a"; done; };
+}
+
+_hostnamectl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --transient --static --pretty --no-ask-password'
+ [ARG]='-H --host -M --machine --json'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --json)
+ comps=$( hostnamectl --json=help 2>/dev/null )
+ ;;
+ *)
+ return 0
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [STANDALONE]='status'
+ [ICONS]='icon-name'
+ [NAME]='hostname deployment location'
+ [CHASSIS]='chassis'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[CHASSIS]}; then
+ comps='desktop laptop convertible server tablet handset watch embedded vm container'
+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _hostnamectl hostnamectl
diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl
new file mode 100644
index 0000000..067b053
--- /dev/null
+++ b/shell-completion/bash/journalctl
@@ -0,0 +1,154 @@
+# journalctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__syslog_priorities=(emerg alert crit err warning notice info debug)
+__syslog_facilities=(kern user mail daemon auth syslog lpr news uucp cron authpriv ftp local0 local1 local2 local3 local4 local5 local6 local7)
+
+_journalctl() {
+ local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-a --all --full --system --user
+ --disk-usage -f --follow --header
+ -h --help -l --local -m --merge --no-pager
+ --no-tail -q --quiet --setup-keys --verify
+ --version --list-catalog --update-catalog --list-boots
+ --show-cursor --dmesg -k --pager-end -e -r --reverse
+ --utc -x --catalog --no-full --force --dump-catalog
+ --flush --rotate --sync --no-hostname -N --fields'
+ [ARG]='-b --boot -D --directory --file -F --field -t --identifier --facility
+ -M --machine -o --output -u --unit --user-unit -p --priority
+ --root --case-sensitive'
+ [ARGUNKNOWN]='-c --cursor --interval -n --lines -S --since -U --until
+ --after-cursor --cursor-file --verify-key -g --grep
+ --vacuum-size --vacuum-time --vacuum-files --output-fields'
+ )
+
+ # Use the default completion for shell redirect operators
+ if __contains_word "$prev" '>' '>>' '&>'; then
+ compopt -o filenames
+ COMPREPLY=( $(compgen -f -- "$cur") )
+ return 0;
+ fi
+
+ if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
+ case $prev in
+ --boot|-b)
+ comps=$(journalctl -F '_BOOT_ID' 2>/dev/null)
+ ;;
+ --directory|-D|--root)
+ comps=$(compgen -d -- "$cur")
+ compopt -o filenames
+ ;;
+ --file)
+ comps=$(compgen -f -- "$cur")
+ compopt -o filenames
+ ;;
+ --output|-o)
+ comps=$( journalctl --output=help 2>/dev/null )
+ ;;
+ --field|-F)
+ comps=$(journalctl --fields | sort 2>/dev/null)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --facility)
+ comps=${__syslog_facilities[*]}
+ ;;
+ --priority|-p)
+ comps=${__syslog_priorities[*]}
+ compopt -o nosort
+ ;;
+ --unit|-u)
+ comps=$(journalctl -F '_SYSTEMD_UNIT' 2>/dev/null)
+ # Similarly to systemctl, we need to distinguish between
+ # escaped and unescaped names in order to be able to correctly
+ # complete them. In this particular case, if the name we're
+ # trying to complete is unescaped (i.e. foo\x2dbaz), escape
+ # it first, so the compgen below works as expected. For more
+ # information about these shenanigans see the systemctl
+ # completion file
+ if ! [[ $cur =~ '\\' ]]; then
+ cur="$(printf '%q' $cur)"
+ fi
+ compopt -o filenames
+ ;;
+ --user-unit)
+ comps=$(journalctl -F '_SYSTEMD_USER_UNIT' 2>/dev/null)
+ ;;
+ --identifier|-t)
+ comps=$(journalctl -F 'SYSLOG_IDENTIFIER' 2>/dev/null)
+ ;;
+ --case-sensitive)
+ comps='yes no'
+ ;;
+ *)
+ return 0
+ ;;
+ esac
+ COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ elif [[ $cur = *=* ]]; then
+ mapfile -t field_vals < <(journalctl -F "${prev%=}" 2>/dev/null)
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
+ elif [[ $cur = /dev* ]]; then
+ compopt -o filenames
+ COMPREPLY=( $(compgen -f -- "${cur}") )
+ elif [[ $cur = /* ]]; then
+ # Append /dev/ to the list of completions, so that
+ # after typing /<TAB><TAB> the user sees /dev/ as one
+ # of the alternatives. Later on the rule above will
+ # take care of showing device files in /dev/.
+ mapfile -t field_vals < <(journalctl -F "_EXE" 2>/dev/null; echo '/dev/')
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur}") )
+ if [[ "${COMPREPLY[@]}" = '/dev/' ]]; then
+ compopt -o filenames
+ COMPREPLY=( $(compgen -f -- "${cur}") )
+ fi
+ elif [[ $prev = '=' ]]; then
+ mapfile -t field_vals < <(journalctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "$cur") )
+ else
+ mapfile -t field_vals < <(journalctl --fields 2>/dev/null)
+ compopt -o nospace
+ COMPREPLY=( $(compgen -W '${field_vals[*]}' -S= -- "$cur") )
+ fi
+}
+
+complete -F _journalctl journalctl
diff --git a/shell-completion/bash/kernel-install b/shell-completion/bash/kernel-install
new file mode 100644
index 0000000..4708777
--- /dev/null
+++ b/shell-completion/bash/kernel-install
@@ -0,0 +1,48 @@
+# kernel-install(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+_kernel_install() {
+ local comps
+ local MACHINE_ID
+ local cur=${COMP_WORDS[COMP_CWORD]}
+
+ case $COMP_CWORD in
+ 1)
+ comps="add remove"
+ ;;
+ 2)
+ comps=$(cd /lib/modules; echo [0-9]*)
+ if [[ ${COMP_WORDS[1]} == "remove" ]] && [[ -f /etc/machine-id ]]; then
+ read MACHINE_ID < /etc/machine-id
+ if [[ $MACHINE_ID ]] && ( [[ -d /boot/$MACHINE_ID ]] || [[ -L /boot/$MACHINE_ID ]] ); then
+ comps=$(cd "/boot/$MACHINE_ID"; echo [0-9]*)
+ fi
+ fi
+ ;;
+ 3)
+ [[ "$cur" ]] || cur=/lib/modules/${COMP_WORDS[2]}/vmlinuz
+ comps=$(compgen -f -- "$cur")
+ compopt -o filenames
+ ;;
+ esac
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _kernel_install kernel-install
diff --git a/shell-completion/bash/localectl b/shell-completion/bash/localectl
new file mode 100644
index 0000000..b601343
--- /dev/null
+++ b/shell-completion/bash/localectl
@@ -0,0 +1,96 @@
+# localectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__locale_fields=( LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME
+ LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER
+ LC_NAME LC_ADDRESS LC_TELEPHONE
+ LC_MEASUREMENT LC_IDENTIFICATION )
+# LC_ALL is omitted on purpose
+
+_localectl() {
+ local i verb comps locale_vals
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local OPTS='-h --help --version --no-convert --no-pager --no-ask-password
+ -H --host -M --machine'
+
+ if __contains_word "$prev" $OPTS; then
+ case $prev in
+ --host|-H)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [STANDALONE]='status list-locales list-keymaps list-x11-keymap-models list-x11-keymap-layouts list-x11-keymap-options'
+ [VARIANTS]='list-x11-keymap-variants'
+ [LOCALES]='set-locale'
+ [KEYMAPS]='set-keymap'
+ [X11]='set-x11-keymap'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[VARIANTS]}; then
+ comps=$(command localectl list-x11-keymap-layouts)
+ elif __contains_word "$verb" ${VERBS[LOCALES]}; then
+ if [[ $cur = *=* ]]; then
+ mapfile -t locale_vals < <(command localectl list-locales 2>/dev/null)
+ COMPREPLY=( $(compgen -W '${locale_vals[*]}' -- "${cur#=}") )
+ elif [[ $prev = "=" ]]; then
+ mapfile -t locale_vals < <(command localectl list-locales 2>/dev/null)
+ COMPREPLY=( $(compgen -W '${locale_vals[*]}' -- "$cur") )
+ else
+ compopt -o nospace
+ COMPREPLY=( $(compgen -W '${__locale_fields[*]}' -S= -- "$cur") )
+ fi
+ return 0
+ elif __contains_word "$verb" ${VERBS[KEYMAPS]}; then
+ comps=$(command localectl list-keymaps)
+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[X11]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _localectl localectl
diff --git a/shell-completion/bash/loginctl b/shell-completion/bash/loginctl
new file mode 100644
index 0000000..b307e42
--- /dev/null
+++ b/shell-completion/bash/loginctl
@@ -0,0 +1,125 @@
+# loginctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_all_sessions () { loginctl --no-legend list-sessions | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+__get_all_users () { loginctl --no-legend list-users | { while read -r a b; do printf "%s\n" "$b"; done; } ; }
+__get_all_seats () { loginctl --no-legend list-seats | { while read -r a b; do printf "%s\n" "$a"; done; } ; }
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+_loginctl () {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a --help -h --no-pager --version
+ --no-legend --no-ask-password -l --full --value'
+ [ARG]='--host -H --kill-whom --property -p --signal -s -M --machine
+ -n --lines -o --output -P'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --signal|-s)
+ _signals
+ return
+ ;;
+ --kill-whom|--kill-who)
+ comps='all leader'
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --property|-p|-P)
+ comps=''
+ ;;
+ --output|-o)
+ comps=$( loginctl --output=help 2>/dev/null )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+ [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+ [SEATS]='seat-status show-seat terminate-seat'
+ [STANDALONE]='list-sessions lock-sessions unlock-sessions list-users list-seats flush-devices'
+ [ATTACH]='attach'
+ )
+
+ 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[SESSIONS]}; then
+ comps=$( __get_all_sessions )
+
+ elif __contains_word "$verb" ${VERBS[USERS]}; then
+ comps=$( __get_all_users )
+
+ elif __contains_word "$verb" ${VERBS[SEATS]}; then
+ comps=$( __get_all_seats )
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+ if [[ $prev = $verb ]]; then
+ comps=$( __get_all_seats )
+ else
+ comps=$(compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _loginctl loginctl
diff --git a/shell-completion/bash/machinectl b/shell-completion/bash/machinectl
new file mode 100644
index 0000000..b28769b
--- /dev/null
+++ b/shell-completion/bash/machinectl
@@ -0,0 +1,117 @@
+# machinectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list-images --full --no-legend --no-pager 2>/dev/null; machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+_machinectl() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a -l --full --help -h --no-ask-password --no-legend --no-pager --version --value
+ --mkdir --read-only --force -q --quiet'
+ [ARG]='--host -H --kill-whom -M --machine --property -p --signal -s --uid -E --setenv -n --lines
+ -o --output --verify --format --max-addresses'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='list list-images clean pull-tar pull-raw list-transfers cancel-transfer import-fs'
+ [MACHINES]='status show start stop login shell enable disable poweroff reboot terminate kill bind
+ copy-to copy-from image-status show-image clone rename read-only remove set-limit
+ export-tar export-raw'
+ [FILE]='import-tar import-raw'
+ )
+
+ _init_completion || return
+
+ 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 __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --signal|-s)
+ _signals
+ return
+ ;;
+ --kill-whom|--kill-who)
+ comps='all leader'
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --property|-p)
+ comps=''
+ ;;
+ --output|-o)
+ comps=$( machinectl --output=help 2>/dev/null )
+ ;;
+ --verify)
+ comps=$( machinectl --verify=help 2>/dev/null )
+ ;;
+ --format)
+ comps='uncompressed xz gzip bzip2'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[MACHINES]}; then
+ comps=$( __get_machines )
+
+ elif __contains_word "$verb" ${VERBS[FILE]}; then
+ comps=$(compgen -f -- "cur")
+ compopt -o filenames
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _machinectl machinectl
diff --git a/shell-completion/bash/meson.build b/shell-completion/bash/meson.build
new file mode 100644
index 0000000..1588b53
--- /dev/null
+++ b/shell-completion/bash/meson.build
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+bashcompletiondir = get_option('bashcompletiondir')
+if bashcompletiondir == ''
+ bash_completion = dependency('bash-completion', required : false)
+ if bash_completion.found()
+ bashcompletiondir = bash_completion.get_variable(pkgconfig : 'completionsdir')
+ else
+ bashcompletiondir = datadir / 'bash-completion/completions'
+ endif
+endif
+
+custom_target(
+ 'systemctl',
+ input : 'systemctl.in',
+ output : 'systemctl',
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
+ install : bashcompletiondir != 'no',
+ install_dir : bashcompletiondir)
+
+items = [['busctl', ''],
+ ['journalctl', ''],
+ ['systemd-analyze', ''],
+ ['systemd-cat', ''],
+ ['systemd-cgls', ''],
+ ['systemd-cgtop', ''],
+ ['systemd-delta', ''],
+ ['systemd-detect-virt', ''],
+ ['systemd-id128', ''],
+ ['systemd-nspawn', ''],
+ ['systemd-path', ''],
+ ['systemd-run', ''],
+ ['udevadm', ''],
+ ['bootctl', ''],
+ ['coredumpctl', 'ENABLE_COREDUMP'],
+ ['homectl', 'ENABLE_HOMED'],
+ ['hostnamectl', 'ENABLE_HOSTNAMED'],
+ ['kernel-install', 'ENABLE_KERNEL_INSTALL'],
+ ['localectl', 'ENABLE_LOCALED'],
+ ['loginctl', 'ENABLE_LOGIND'],
+ ['machinectl', 'ENABLE_MACHINED'],
+ ['networkctl', 'ENABLE_NETWORKD'],
+ ['oomctl', 'ENABLE_OOMD'],
+ ['portablectl', 'ENABLE_PORTABLED'],
+ ['resolvectl', 'ENABLE_RESOLVE'],
+ ['systemd-cryptenroll', 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-dissect', 'HAVE_BLKID'],
+ ['systemd-resolve', 'ENABLE_RESOLVE'],
+ ['systemd-sysext', 'ENABLE_SYSEXT'],
+ ['timedatectl', 'ENABLE_TIMEDATED']]
+
+foreach item : items
+ if bashcompletiondir != 'no' and (item[1] == '' or conf.get(item[1]) == 1)
+ install_data(item[0],
+ install_dir : bashcompletiondir)
+ endif
+endforeach
diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl
new file mode 100644
index 0000000..db59a9c
--- /dev/null
+++ b/shell-completion/bash/networkctl
@@ -0,0 +1,84 @@
+# networkctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+ return 1
+}
+
+__get_links() {
+ networkctl list --no-legend --no-pager --all --full | { while read -r a b c; do echo " $b"; done; };
+}
+
+_networkctl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-a --all -h --help --version --no-pager --no-legend -s --stats -l --full'
+ [ARG]='-n --lines --json'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='label reload'
+ [LINKS]='status list lldp delete renew up down forcerenew reconfigure'
+ )
+
+ _init_completion || return
+
+ 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 __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --json)
+ comps=$(networkctl --json=help | sort 2>/dev/null)
+ ;;
+ *)
+ return 0
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[LINKS]}; then
+ comps=$( __get_links )
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _networkctl networkctl
diff --git a/shell-completion/bash/oomctl b/shell-completion/bash/oomctl
new file mode 100644
index 0000000..dc45ba5
--- /dev/null
+++ b/shell-completion/bash/oomctl
@@ -0,0 +1,57 @@
+# oomctl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_oomctl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local OPTS='-h --help --version --no-pager'
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ local -A VERBS=(
+ [STANDALONE]='help dump'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _oomctl oomctl
diff --git a/shell-completion/bash/portablectl b/shell-completion/bash/portablectl
new file mode 100644
index 0000000..30e5da4
--- /dev/null
+++ b/shell-completion/bash/portablectl
@@ -0,0 +1,116 @@
+# portablectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+_portablectl() {
+ local i n comps verb
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-q --quiet --runtime --no-reload --cat --no-pager --no-legend
+ --no-ask-password --enable --now -h --help --version'
+ [ARG]='-p --profile --copy -H --host -M --machine --extension'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='list'
+ [IMAGE]='attach detach reattach inspect is-attached set-limit'
+ [IMAGES]='remove'
+ [IMAGE_WITH_BOOL]='read-only'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --profile|-p)
+ comps="default nonetwork strict trusted"
+ ;;
+ --copy)
+ comps="copy symlink auto"
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --extension)
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ 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
+
+ n=$((COMP_CWORD - i))
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[IMAGE]}; then
+ if [[ $n == 1 ]]; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ else
+ comps=''
+ fi
+ elif __contains_word "$verb" ${VERBS[IMAGES]}; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ elif __contains_word "$verb" ${VERBS[IMAGE_WITH_BOOL]}; then
+ if [[ $n == 1 ]]; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ elif [[ $n == 2 ]]; then
+ comps='yes no'
+ else
+ comps=''
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _portablectl portablectl
diff --git a/shell-completion/bash/resolvectl b/shell-completion/bash/resolvectl
new file mode 100644
index 0000000..bd3e8bf
--- /dev/null
+++ b/shell-completion/bash/resolvectl
@@ -0,0 +1,204 @@
+# resolvectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_interfaces(){
+ local name
+ for name in $(cd /sys/class/net && command ls); do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
+}
+
+_resolvectl() {
+ local i comps verb name
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version -4 -6 --legend=no --cname=no
+ --validate=no --synthesize=no --cache=no --zone=no
+ --trust-anchor=no --network=no --service-address=no
+ --service-txt=no --search=no --stale-data=no --no-pager'
+ [ARG]='-t --type -c --class -i --interface -p --protocol --raw'
+ )
+ local -A VERBS=(
+ [DOMAIN]='query service openpgp'
+ [FAMILY]='tlsa'
+ [STATUS]='status'
+ [LINK]='revert dns domain nta'
+ [BOOLEAN]='default-route'
+ [RESOLVE]='llmnr mdns'
+ [DNSSEC]='dnssec'
+ [DNSOVERTLS]='dnsovertls'
+ [STANDALONE]='statistics reset-statistics flush-caches reset-server-features show-cache'
+ [LOG_LEVEL]='log-level'
+ )
+ local -A ARGS=(
+ [FAMILY]='tcp udp sctp'
+ [BOOLEAN]='yes no'
+ [RESOLVE]='yes no resolve'
+ [DNSSEC]='yes no allow-downgrade'
+ [DNSOVERTLS]='yes no opportunistic'
+ )
+ local interfaces=$( __get_interfaces )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --interface|-i)
+ comps="$interfaces"
+ ;;
+ --protocol|-p|--type|-t|--class|-c)
+ comps=$( resolvectl --legend=no "$prev" help; echo help )
+ ;;
+ --raw)
+ comps="payload packet"
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ 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[STANDALONE]} ${VERBS[DOMAIN]}; then
+ comps=''
+
+ elif __contains_word "$verb" ${VERBS[STATUS]}; then
+ comps="$interfaces"
+
+ elif __contains_word "$verb" ${VERBS[LOG_LEVEL]}; then
+ comps='debug info notice warning err crit alert emerg'
+
+ elif __contains_word "$verb" ${VERBS[FAMILY]}; then
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${ARGS[FAMILY]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+ if [[ -z $name ]]; then
+ comps=${ARGS[FAMILY]}
+ else
+ comps=""
+ fi
+
+ elif __contains_word "$verb" ${VERBS[LINK]} ${VERBS[BOOLEAN]} ${VERBS[RESOLVE]} ${VERBS[DNSSEC]} ${VERBS[DNSOVERTLS]}; then
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" $interfaces &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps="$interfaces"
+
+ elif __contains_word "$verb" ${VERBS[RESOLVE]}; then
+ name=
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${ARGS[RESOLVE]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps=${ARGS[RESOLVE]}
+ else
+ comps=''
+ fi
+
+ elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
+ name=
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${ARGS[BOOLEAN]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps=${ARGS[BOOLEAN]}
+ else
+ comps=''
+ fi
+
+ elif __contains_word "$verb" ${VERBS[DNSSEC]}; then
+ name=
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${ARGS[DNSSEC]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps=${ARGS[DNSSEC]}
+ else
+ comps=''
+ fi
+
+ elif __contains_word "$verb" ${VERBS[DNSOVERTLS]}; then
+ name=
+ for ((i++; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${ARGS[DNSOVERTLS]} &&
+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
+ name=${COMP_WORDS[i]}
+ break;
+ fi
+ done
+
+ if [[ -z $name ]]; then
+ comps=${ARGS[DNSOVERTLS]}
+ else
+ comps=''
+ fi
+
+ else
+ comps=''
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _resolvectl resolvectl
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
new file mode 100644
index 0000000..5c444b7
--- /dev/null
+++ b/shell-completion/bash/systemctl.in
@@ -0,0 +1,406 @@
+# systemctl(1) completion -*- shell-script -*-
+# vi: ft=sh
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# Copyright © 2010 Ran Benita
+
+__systemctl() {
+ local mode=$1; shift 1
+ systemctl $mode --full --legend=no --no-pager --plain "$@" 2>/dev/null
+}
+
+__systemd_properties() {
+ {{LIBEXECDIR}}/systemd --dump-bus-properties
+}
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+{% raw -%}
+__filter_units_by_properties () {
+ local mode=$1 properties=$2; shift 2
+ local units=("$@")
+ local props i p n
+ local names= count=0
+
+ IFS=$',' read -r -a p < <(echo "Names,$properties")
+ n=${#p[*]}
+ readarray -t props < \
+ <(__systemctl $mode show --property "Names,$properties" -- "${units[@]}")
+
+ for ((i=0; i < ${#props[*]}; i++)); do
+ if [[ -z ${props[i]} ]]; then
+ if (( count == n )) && [[ -n $names ]]; then
+ echo $names
+ fi
+ names=
+ count=0
+ else
+ (( count++ ))
+ if [[ ${props[i]%%=*} == 'Names' ]]; then
+ names=${props[i]#*=}
+ fi
+ fi
+ done
+ if (( count == n )) && [[ -n $names ]]; then
+ echo $names
+ fi
+}
+{% endraw %}
+
+__get_all_units () { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \
+ | { while read -r a b; do echo " $a"; done; }; }
+__get_non_template_units() { { __systemctl $1 list-unit-files "$2*"; __systemctl $1 list-units --all "$2*"; } \
+ | { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; }
+__get_template_names () { __systemctl $1 list-unit-files "$2*" \
+ | { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; }
+__get_active_units () { __systemctl $1 list-units "$2*" \
+ | { while read -r a b; do echo " $a"; done; }; }
+__get_active_services() { __systemctl $1 list-units "$2*.service" \
+ | { while read -r a b; do echo " $a"; done; }; }
+
+__get_not_masked_unit_files() {
+ # filter out masked, not-found, or template units.
+ __systemctl $1 list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient "$2*" | \
+ { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
+}
+
+__get_startable_units () {
+ __filter_units_by_properties $1 ActiveState=inactive,CanStart=yes $(
+ { __get_not_masked_unit_files $1 $2
+ # get inactive template units
+ __systemctl $1 list-units --state inactive,failed "$2*" | \
+ { 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_properties $1 CanStart=yes $(
+ { __get_not_masked_unit_files $1 $2
+ __get_active_units $1 $2
+ } | sort -u )
+}
+
+__get_stoppable_units () {
+ # filter out masked and not-found
+ local units=$(
+ { __get_not_masked_unit_files $1 $2
+ __get_active_units $1 $2
+ } | sort -u )
+ __filter_units_by_properties $1 ActiveState=active,CanStop=yes $units
+ __filter_units_by_properties $1 ActiveState=reloading,CanStop=yes $units
+ __filter_units_by_properties $1 ActiveState=activating,CanStop=yes $units
+}
+
+__get_reloadable_units () {
+ # filter out masked and not-found
+ __filter_units_by_properties $1 ActiveState=active,CanReload=yes $(
+ { __get_not_masked_unit_files $1 $2
+ __get_active_units $1 $2
+ } | sort -u )
+}
+
+__get_failed_units() { __systemctl $1 list-units "$2*" \
+ | while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }
+__get_enabled_units() { __systemctl $1 list-unit-files "$2*" \
+ | while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }
+__get_disabled_units() { __systemctl $1 list-unit-files "$2*" \
+ | while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }
+__get_masked_units() { __systemctl $1 list-unit-files "$2*" \
+ | while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }
+__get_all_unit_files() { __systemctl $1 list-unit-files "$2*" | while read -r a b; do echo " $a"; done; }
+
+__get_machines() {
+ local a
+
+ while read a _; do
+ echo " $a"
+ done < <(machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null | sort -u; echo ".host")
+}
+
+_systemctl () {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local i verb comps mode cur_orig
+
+ local -A OPTS=(
+ [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
+ --help -h --no-ask-password --no-block --legend=no --no-pager --no-reload --no-wall --now
+ --quiet -q --system --user --version --runtime --recursive -r --firmware-setup
+ --show-types --plain --failed --value --fail --dry-run --wait --no-warn --with-dependencies
+ --show-transaction -T --mkdir --marked --read-only'
+ [ARG]='--host -H --kill-whom --property -p -P --signal -s --type -t --state --job-mode --root
+ --preset-mode -n --lines -o --output -M --machine --message --timestamp --check-inhibitors --what
+ --image --boot-loader-menu --boot-loader-entry --reboot-argument --drop-in'
+ )
+
+ 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-whom|--kill-who)
+ comps='all control main'
+ ;;
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o filenames
+ ;;
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --property|-p|-P)
+ comps=$(__systemd_properties)
+ ;;
+ --preset-mode)
+ comps='full enable-only disable-only'
+ ;;
+ --output|-o)
+ comps=$( systemctl --output=help 2>/dev/null )
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --timestamp)
+ comps='pretty us µs utc us+utc µs+utc'
+ ;;
+ --check-inhibitors)
+ comps='auto yes no'
+ ;;
+ --what)
+ comps='configuration state cache logs runtime all'
+ ;;
+ --image)
+ comps=$(compgen -A file -- "$cur")
+ compopt -o filenames
+ ;;
+ --boot-loader-entry)
+ comps=$(systemctl --boot-loader-entry=help 2>/dev/null)
+ ;;
+ 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]='cat mask'
+ [NONTEMPLATE_UNITS]='is-active is-failed is-enabled status show 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 freeze thaw'
+ [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 whoami
+ emergency exit halt hibernate hybrid-sleep
+ suspend-then-hibernate kexec soft-reboot list-jobs list-sockets
+ list-timers list-units list-unit-files poweroff
+ reboot rescue show-environment suspend get-default
+ is-system-running preset-all list-automounts list-paths'
+ [FILE]='link switch-root'
+ [TARGETS]='set-default'
+ [MACHINES]='list-machines'
+ [LOG_LEVEL]='log-level'
+ [LOG_TARGET]='log-target'
+ [SERVICE_LOG_LEVEL]='service-log-level'
+ [SERVICE_LOG_TARGET]='service-log-target'
+ [SERVICE_WATCHDOGS]='service-watchdogs'
+ [MOUNT]='bind mount-image'
+ )
+
+ 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
+
+ # When trying to match a unit name with certain special characters in its name (i.e
+ # foo\x2dbar:01) they get (un)escaped by bash along the way, thus causing any possible
+ # match to fail.
+ # The following condition solves two cases:
+ # 1) We're trying to complete an already escaped unit name part,
+ # i.e foo\\x2dba. In this case we need to unescape the name, so it
+ # gets properly matched with the systemctl output (i.e. foo\x2dba).
+ # However, we need to keep the original escaped name as well for the
+ # final match, as the completion machinery does the unescaping
+ # automagically.
+ # 2) We're trying to complete an unescaped (literal) unit name part,
+ # i.e. foo\x2dba. That means we don't have to do the unescaping
+ # required for correct matching with systemctl's output, however,
+ # we need to escape the name for the final match, where the completion
+ # expects the string to be escaped.
+ cur_orig=$cur
+ if [[ $cur =~ '\\' ]]; then
+ cur="$(echo $cur | xargs echo)"
+ else
+ cur_orig="$(printf '%q' $cur)"
+ fi
+
+ if [[ -z ${verb-} ]]; then
+ comps="${VERBS[*]}"
+
+ elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+ comps=$( __get_all_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[NONTEMPLATE_UNITS]}; then
+ comps=$( __get_non_template_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+ comps=$( __get_enabled_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+ comps=$( __get_disabled_units $mode "$cur";
+ __get_template_names $mode "$cur")
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then
+ comps=$( __get_disabled_units $mode "$cur";
+ __get_enabled_units $mode "$cur";
+ __get_template_names $mode "$cur")
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+ comps=$( __get_startable_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
+ comps=$( __get_restartable_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
+ comps=$( __get_stoppable_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
+ comps=$( __get_reloadable_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
+ comps=$( __filter_units_by_properties $mode AllowIsolate=yes \
+ $( __get_non_template_units $mode "$cur" ) )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+ comps=$( __get_failed_units $mode "$cur" )
+ compopt -o filenames
+
+ elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+ comps=$( __get_masked_units $mode "$cur" )
+ 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 "$cur*" \
+ | { while read -r a b; do echo " $a"; done; } )
+ else
+ comps=$( __get_all_unit_files $mode "$cur" )
+ 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 [ "$verb" = 'unset-environment' ]; then
+ comps=$( __systemctl $mode show-environment \
+ | while read -r line; do echo " ${line%%=*}"; done )
+ compopt -o nospace
+
+ elif [ "$verb" = 'set-environment' ]; then
+ comps=$( __systemctl $mode show-environment \
+ | while read -r line; do echo " ${line%%=*}="; done )
+ compopt -o nospace
+
+ elif [ "$verb" = 'import-environment' ]; then
+ COMPREPLY=( $(compgen -A variable -- "$cur_orig") )
+ return 0
+
+ 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 "$cur*" \
+ | { while read -r a b; do echo " $a"; done; } )
+ elif __contains_word "$verb" ${VERBS[LOG_LEVEL]}; then
+ comps='debug info notice warning err crit alert emerg'
+ elif __contains_word "$verb" ${VERBS[LOG_TARGET]}; then
+ comps='console journal kmsg journal-or-kmsg null'
+ elif __contains_word "$verb" ${VERBS[SERVICE_LOG_LEVEL]}; then
+ if __contains_word "$prev" ${VERBS[SERVICE_LOG_LEVEL]}; then
+ comps=$( __get_all_unit_files $mode "$cur" )
+ elif __contains_word "$prev" debug info notice warning err crit alert emerg; then
+ return 0
+ else
+ comps='debug info notice warning err crit alert emerg'
+ fi
+ elif __contains_word "$verb" ${VERBS[SERVICE_LOG_TARGET]}; then
+ if __contains_word "$prev" ${VERBS[SERVICE_LOG_TARGET]}; then
+ comps=$( __get_all_unit_files $mode "$cur" )
+ elif __contains_word "$prev" console journal kmsg journal-or-kmsg null; then
+ return 0
+ else
+ comps='console journal kmsg journal-or-kmsg null'
+ fi
+ elif __contains_word "$verb" ${VERBS[SERVICE_WATCHDOGS]}; then
+ comps='on off'
+ elif __contains_word "$verb" ${VERBS[MOUNT]}; then
+ if __contains_word "$prev" ${VERBS[MOUNT]}; then
+ comps=$( __get_active_services $mode "$cur" )
+ elif [[ "$prev" =~ .service ]]; then
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ else
+ return 0
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur_orig") )
+ return 0
+}
+
+complete -F _systemctl systemctl
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
new file mode 100644
index 0000000..1fde672
--- /dev/null
+++ b/shell-completion/bash/systemd-analyze
@@ -0,0 +1,207 @@
+# systemd-analyze(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__get_units_all() {
+ systemctl list-units --no-legend --no-pager --plain --all $1 | \
+ { while read -r a b c; do echo " $a"; done }
+}
+
+__get_services() {
+ systemctl list-units --no-legend --no-pager --plain -t service --all $1 | \
+ { while read -r a b c; do [[ $b == "loaded" ]]; echo " $a"; done }
+}
+
+__get_syscall_sets() {
+ local line
+ systemd-analyze syscall-filter --no-pager | while IFS= read -r line; do
+ if [[ $line == @* ]]; then
+ printf '%s\n' "$line"
+ fi
+ done
+}
+
+_systemd_analyze() {
+ local i verb comps mode
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --system --user --global --order --require --no-pager
+ --man=no --generators=yes -q --quiet'
+ [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='time blame unit-paths exit-status calendar timestamp timespan'
+ [CRITICAL_CHAIN]='critical-chain'
+ [DOT]='dot'
+ [DUMP]='dump'
+ [VERIFY]='verify'
+ [SECCOMP_FILTER]='syscall-filter'
+ [CAT_CONFIG]='cat-config'
+ [SECURITY]='security'
+ [CONDITION]='condition'
+ [INSPECT_ELF]='inspect-elf'
+ [PLOT]='plot'
+ )
+
+ local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
+ systemd/journal-remote.conf systemd/journal-upload.conf systemd/logind.conf
+ systemd/resolved.conf systemd/networkd.conf systemd/resolved.conf
+ systemd/sleep.conf systemd/system.conf systemd/timedated.conf
+ systemd/timesyncd.conf systemd/user.conf udev/udev.conf'
+
+ _init_completion || return
+
+ 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 __contains_word "--user" ${COMP_WORDS[*]}; then
+ mode=--user
+ else
+ mode=--system
+ fi
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ -z ${verb-} && $cur = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+
+ elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --global --no-pager'
+ fi
+
+ elif __contains_word "$verb" ${VERBS[CRITICAL_CHAIN]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --fuzz --no-pager'
+ else
+ comps=$( __get_units_all $mode )
+ fi
+
+ elif __contains_word "$verb" ${VERBS[DOT]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --global --from-pattern --to-pattern --order --require'
+ fi
+
+ elif __contains_word "$verb" ${VERBS[DUMP]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --no-pager'
+ else
+ comps=$( __get_units_all $mode )
+ fi
+
+ elif __contains_word "$verb" ${VERBS[SECCOMP_FILTER]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --no-pager'
+ else
+ comps=$( __get_syscall_sets )
+ fi
+
+ elif __contains_word "$verb" ${VERBS[VERIFY]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --global --man=no --generators=yes --root --image --recursive-errors=no --recursive-errors=yes --recursive-errors=one'
+ else
+ comps=$( compgen -A file -- "$cur";
+ __get_units_all $mode )
+ compopt -o filenames
+ fi
+
+ elif __contains_word "$verb" ${VERBS[CAT_CONFIG]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --root --no-pager'
+ elif [[ -z $cur ]]; then
+ comps="$CONFIGS"
+ compopt -o filenames
+ else
+ comps="$CONFIGS $( compgen -A file -- "$cur" )"
+ compopt -o filenames
+ fi
+
+ elif __contains_word "$verb" ${VERBS[SECURITY]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --no-pager --system --user -H --host -M --machine --offline --threshold --security-policy --json=off --json=pretty --json=short --root --image --profile=default --profile=nonetwork --profile=strict --profile=trusted'
+ elif ! __contains_word "--offline" ${COMP_WORDS[*]}; then
+ comps=$( __get_services $mode )
+ else
+ comps="$CONFIGS $( compgen -A file -- "$cur" )"
+ compopt -o filenames
+ fi
+
+ elif __contains_word "$verb" ${VERBS[CONDITION]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --global --no-pager --root --image'
+ elif [[ $prev = "-u" ]] || [[ $prev = "--unit" ]]; then
+ comps=$( __get_services $mode )
+ fi
+
+ elif __contains_word "$verb" ${VERBS[INSPECT_ELF]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --json=off --json=pretty --json=short'
+ else
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+
+ elif __contains_word "$verb" ${VERBS[PLOT]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --global --no-pager --json=off --json=pretty --json=short --table --no-legend'
+ fi
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd_analyze systemd-analyze
diff --git a/shell-completion/bash/systemd-cat b/shell-completion/bash/systemd-cat
new file mode 100644
index 0000000..b209140
--- /dev/null
+++ b/shell-completion/bash/systemd-cat
@@ -0,0 +1,57 @@
+# systemd-cat(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd_cat() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version'
+ [ARG]='-t --identifier -p --priority --level-prefix'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --identifier|-t)
+ comps=''
+ ;;
+ --priority|-p)
+ comps='emerg alert crit err warning notice info debug'
+ ;;
+ --level-prefix)
+ comps='yes no'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_cat systemd-cat
diff --git a/shell-completion/bash/systemd-cgls b/shell-completion/bash/systemd-cgls
new file mode 100644
index 0000000..8dda5a8
--- /dev/null
+++ b/shell-completion/bash/systemd-cgls
@@ -0,0 +1,71 @@
+# systemd-cgls(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__get_units_have_cgroup() {
+ systemctl $1 --full --no-legend --no-pager --plain list-units | {
+ while read -r a b c d; do
+ [[ $c == "active" && ${a##*.} =~ (service|socket|mount|swap|slice|scope) ]] && echo " $a"
+ done
+ };
+}
+
+_systemd_cgls() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --all -l --full -k --no-pager --xattr=no --cgroup-id=no'
+ [ARG]='-M --machine -u --unit --user-unit'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --unit|-u)
+ comps=$( __get_units_have_cgroup --system )
+ ;;
+ --user-unit)
+ comps=$( __get_units_have_cgroup --user )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_cgls systemd-cgls
diff --git a/shell-completion/bash/systemd-cgtop b/shell-completion/bash/systemd-cgtop
new file mode 100644
index 0000000..731d9c9
--- /dev/null
+++ b/shell-completion/bash/systemd-cgtop
@@ -0,0 +1,68 @@
+# systemd-cgtop(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+_systemd_cgtop() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local comps
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version -p -t -c -m -i -b --batch -r --raw -k -P'
+ [ARG]='--cpu --depth -M --machine --recursive -n --iterations -d --delay --order'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --recursive)
+ comps='yes no'
+ ;;
+ --order)
+ comps='path tasks cpu memory io'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ if [ -d /sys/fs/cgroup/systemd/ ]; then
+ COMPREPLY+=( $(cd /sys/fs/cgroup/systemd/ && compgen -o nospace -o dirnames "$cur") )
+ elif [ -d /sys/fs/cgroup/ ]; then
+ COMPREPLY+=( $(cd /sys/fs/cgroup/ && compgen -o nospace -o dirnames "$cur") )
+ fi
+}
+
+complete -F _systemd_cgtop systemd-cgtop
diff --git a/shell-completion/bash/systemd-confext b/shell-completion/bash/systemd-confext
new file mode 100644
index 0000000..c8eca3b
--- /dev/null
+++ b/shell-completion/bash/systemd-confext
@@ -0,0 +1,85 @@
+# systemd-confext(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd-confext() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version
+ --no-pager
+ --no-legend
+ --force'
+ [ARG]='--root
+ --json'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='status
+ merge
+ unmerge
+ refresh
+ list'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o dirnames
+ ;;
+ --json)
+ comps='pretty short off'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ 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[STANDALONE]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd-confext systemd-confext
diff --git a/shell-completion/bash/systemd-cryptenroll b/shell-completion/bash/systemd-cryptenroll
new file mode 100644
index 0000000..1723f75
--- /dev/null
+++ b/shell-completion/bash/systemd-cryptenroll
@@ -0,0 +1,117 @@
+# systemd-cryptenroll(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_fido2_devices() {
+ local i
+ for i in /dev/hidraw*; do
+ [ -c "$i" ] && printf '%s\n' "$i"
+ done
+}
+
+__get_tpm2_devices() {
+ local i
+ for i in /dev/tpmrm*; do
+ [ -c "$i" ] && printf '%s\n' "$i"
+ done
+}
+
+__get_block_devices() {
+ local i
+ for i in /dev/*; do
+ [ -b "$i" ] && printf '%s\n' "$i"
+ done
+}
+
+_systemd_cryptenroll() {
+ local comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version
+ --password --recovery-key'
+ [ARG]='--unlock-key-file
+ --unlock-fido2-device
+ --pkcs11-token-uri
+ --fido2-credential-algorithm
+ --fido2-device
+ --fido2-with-client-pin
+ --fido2-with-user-presence
+ --fido2-with-user-verification
+ --tpm2-device
+ --tpm2-device-key
+ --tpm2-seal-key-handle
+ --tpm2-pcrs
+ --tpm2-public-key
+ --tpm2-public-key-pcrs
+ --tpm2-signature
+ --tpm2-with-pin
+ --tpm2-pcrlock
+ --wipe-slot'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --unlock-key-file|--tpm2-device-key|--tpm2-public-key|--tpm2-signature|--tpm2-pcrlock)
+ comps=$(compgen -A file -- "$cur")
+ compopt -o filenames
+ ;;
+ --unlock-fido2-device)
+ comps="auto $(__get_fido2_devices)"
+ ;;
+ --pkcs11-token-uri)
+ comps='auto list pkcs11:'
+ ;;
+ --fido2-credential-algorithm)
+ comps='es256 rs256 eddsa'
+ ;;
+ --fido2-device)
+ comps="auto list $(__get_fido2_devices)"
+ ;;
+ --fido2-with-client-pin|--fido2-with-user-presence|--fido2-with-user-verification|--tpm2-with-pin)
+ comps='yes no'
+ ;;
+ --tpm2-device)
+ comps="auto list $(__get_tpm2_devices)"
+ ;;
+ --wipe-slot)
+ comps='all empty password recovery pkcs11 fido2 tpm2'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ comps=$(__get_block_devices)
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd_cryptenroll systemd-cryptenroll
diff --git a/shell-completion/bash/systemd-delta b/shell-completion/bash/systemd-delta
new file mode 100644
index 0000000..b148755
--- /dev/null
+++ b/shell-completion/bash/systemd-delta
@@ -0,0 +1,60 @@
+# systemd-delta(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd-delta() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local comps
+
+ local -A OPTS=(
+ [STANDALONE]='--help -h --no-pager --version'
+ [ARG]='--diff --type -t'
+ )
+
+ _init_completion || return
+
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --diff)
+ comps='yes no'
+ ;;
+ --type|-t)
+ comps='masked equivalent redirected overridden unchanged extended default'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]] || [[ -z ${comps-} ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -W '${comps-}' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd-delta systemd-delta
diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt
new file mode 100644
index 0000000..9ade2af
--- /dev/null
+++ b/shell-completion/bash/systemd-detect-virt
@@ -0,0 +1,40 @@
+# systemd-detect-virt(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd_detect_virt() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet --cvm
+ --private-users --list --list-cvm'
+ )
+
+ _init_completion || return
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_detect_virt systemd-detect-virt
diff --git a/shell-completion/bash/systemd-dissect b/shell-completion/bash/systemd-dissect
new file mode 100644
index 0000000..17fb642
--- /dev/null
+++ b/shell-completion/bash/systemd-dissect
@@ -0,0 +1,127 @@
+# systemd-dissect(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd_dissect() {
+ local comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev_1=${COMP_WORDS[COMP_CWORD-1]} prev_2=${COMP_WORDS[COMP_CWORD-2]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version
+ --discover
+ --no-pager
+ --no-legend
+ -r --read-only
+ --mkdir
+ --rmdir
+ --in-memory'
+ [ARG]='-m --mount -M
+ -u --umount -U
+ --attach
+ --detach
+ -l --list
+ --mtree
+ --with
+ -x --copy-from
+ -a --copy-to
+ --validate
+ --fsck
+ --growfs
+ --discard
+ --root-hash
+ --root-hash-sig
+ --verity-data
+ --image-policy
+ --json
+ --loop-ref
+ --mtree-hash'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev_1" ${OPTS[STANDALONE]}; then
+ case $prev_1 in
+ -h|--help|--version|--discover)
+ return 0
+ ;;
+ esac
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ if __contains_word "$prev_1" ${OPTS[ARG]}; then
+ case $prev_1 in
+ -l|--list|--mtree|-m|--mount|-M|--attach|--detach|-x|--copy-from|-a|--copy-to|--verity-data|--validate|--with)
+ comps=$(compgen -A file -- "$cur")
+ compopt -o filenames
+ ;;
+ -u|--umount|-U)
+ comps=$(compgen -A directory -- "$cur")
+ compopt -o dirnames
+ ;;
+ --fsck|--growfs|--mtree-hash)
+ comps='yes no'
+ ;;
+ --discard)
+ comps='disabled loop all crypto'
+ ;;
+ --root-hash-sig)
+ comps="base64: $(compgen -A file -- "$cur")"
+ compopt -o filenames
+ ;;
+ --json)
+ comps='pretty short off'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if __contains_word "$prev_2" ${OPTS[ARG]}; then
+ case $prev_2 in
+ -m|--mount|-M)
+ comps=$(compgen -A directory -- "$cur")
+ compopt -o dirnames
+ ;;
+ --with)
+ comps=$(compgen -A command -- "$cur")
+ compopt -o filenames
+ ;;
+ *)
+ comps=$(compgen -A file -- "$cur")
+ compopt -o filenames
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -A file -- "$cur") )
+ compopt -o filenames
+ return 0
+}
+
+complete -F _systemd_dissect systemd-dissect
diff --git a/shell-completion/bash/systemd-id128 b/shell-completion/bash/systemd-id128
new file mode 100644
index 0000000..1c19639
--- /dev/null
+++ b/shell-completion/bash/systemd-id128
@@ -0,0 +1,74 @@
+# systemd-id128(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+ return 1
+}
+
+_systemd_id128() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version -p --pretty'
+ [ARG]='-a --app-specific'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='new machine-id boot-id invocation-id help'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --app-specific|-a)
+ comps=""
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ 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[STANDALONE]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd_id128 systemd-id128
diff --git a/shell-completion/bash/systemd-nspawn b/shell-completion/bash/systemd-nspawn
new file mode 100644
index 0000000..cc3d2f6
--- /dev/null
+++ b/shell-completion/bash/systemd-nspawn
@@ -0,0 +1,200 @@
+# systemd-nspawn(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_users() {
+ local a b
+ loginctl list-users --no-legend --no-pager | { while read a b; do echo " $b"; done; };
+}
+
+__get_slices() {
+ local a b
+ systemctl list-units -t slice --no-legend --no-pager --plain | { while read a b; do echo " $a"; done; };
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__get_env() {
+ local a
+ env | { while read a; do echo " ${a%%=*}"; done; };
+}
+
+__get_interfaces(){
+ local name
+ for name in $(cd /sys/class/net && command ls); do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
+}
+
+__get_rlimit() {
+ local i
+ for i in $(systemd-nspawn --rlimit=help 2>/dev/null); do
+ echo " ${i}="
+ done
+}
+
+_systemd_nspawn() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local i verb comps
+
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --private-network -b --boot --read-only -q --quiet --share-system
+ --keep-unit -n --network-veth -j -x --ephemeral -a --as-pid2 -U --suppress-sync=yes'
+ [ARG]='-D --directory -u --user --uuid --capability --drop-capability --link-journal --bind --bind-ro
+ -M --machine -S --slice -E --setenv -Z --selinux-context -L --selinux-apifs-context
+ --register --network-interface --network-bridge --personality -i --image --tmpfs
+ --volatile --network-macvlan --kill-signal --template --notify-ready --root-hash --chdir
+ --pivot-root --property --private-users --private-users-ownership --network-namespace-path
+ --network-ipvlan --network-veth-extra --network-zone -p --port --system-call-filter --overlay
+ --overlay-ro --settings --rlimit --hostname --no-new-privileges --oom-score-adjust --cpu-affinity
+ --resolv-conf --timezone --root-hash-sig'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --directory|-D|--template)
+ compopt -o nospace
+ comps=$(compgen -S/ -A directory -- "$cur" )
+ ;;
+ --user|-u)
+ comps=$( __get_users )
+ ;;
+ --uuid|--root-hash)
+ comps=''
+ ;;
+ --capability)
+ comps='CAP_BLOCK_SUSPEND CAP_IPC_LOCK CAP_MAC_ADMIN CAP_MAC_OVERRIDE CAP_SYS_MODULE CAP_SYS_PACCT CAP_SYS_RAWIO
+ CAP_SYS_TIME CAP_SYSLOG CAP_WAKE_ALARM CAP_NET_ADMIN'
+ ;;
+ --drop-capability)
+ comps='CAP_AUDIT_CONTROL CAP_AUDIT_WRITE CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_FSETID
+ CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE CAP_MKNOD CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+ CAP_NET_BROADCAST CAP_NET_RAW CAP_SETFCAP CAP_SETGID CAP_SETPCAP CAP_SETUID CAP_SYS_ADMIN CAP_SYS_BOOT
+ CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_RESOURCE CAP_SYS_TTY_CONFIG'
+ ;;
+ --link-journal)
+ comps='no auto guest try-guest host try-host'
+ ;;
+ --bind|--bind-ro)
+ compopt -o nospace -o filenames
+ comps=$(compgen -f -- "$cur" )
+ ;;
+ --tmpfs)
+ compopt -o nospace
+ comps=$(compgen -S/ -A directory -- "$cur" )
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
+ ;;
+ --slice|-S)
+ comps=$( __get_slices )
+ ;;
+ --setenv|-E)
+ comps=$( __get_env )
+ ;;
+ --selinux-context|-Z)
+ comps=''
+ ;;
+ --selinux-apifs-context|-L)
+ comps=''
+ ;;
+ --register)
+ comps='yes no'
+ ;;
+ --network-interface)
+ comps=$(__get_interfaces)
+ ;;
+ --network-bridge)
+ comps=''
+ ;;
+ --network-macvlan)
+ comps=''
+ ;;
+ --personality)
+ comps='x86 x86-64'
+ ;;
+ --volatile)
+ comps=$( systemd-nspawn --volatile=help 2>/dev/null )
+ ;;
+ --image|-i)
+ compopt -o nospace
+ comps=$( compgen -A file -- "$cur" )
+ ;;
+ --kill-signal)
+ _signals
+ return
+ ;;
+ --notify-ready)
+ comps='yes no'
+ ;;
+ --private-users)
+ comps='yes no pick'
+ ;;
+ --network-namespace-path)
+ comps=$( compgen -A file -- "$cur" )
+ ;;
+ --settings)
+ comps='yes no override trusted'
+ ;;
+ --rlimit)
+ comps=$( __get_rlimit )
+ ;;
+ --hostname)
+ comps=''
+ ;;
+ --no-new-privileges)
+ comps='yes no'
+ ;;
+ --oom-score-adjust)
+ comps=''
+ ;;
+ --cpu-affinity)
+ comps=''
+ ;;
+ --resolv-conf)
+ comps=$( systemd-nspawn --resolv-conf=help 2>/dev/null )
+ ;;
+ --timezone)
+ comps=$( systemd-nspawn --timezone=help 2>/dev/null )
+ ;;
+ --root-hash-sig)
+ compopt -o nospace
+ comps=$( compgen -A file -- "$cur" )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_nspawn systemd-nspawn
diff --git a/shell-completion/bash/systemd-path b/shell-completion/bash/systemd-path
new file mode 100644
index 0000000..40e2f7e
--- /dev/null
+++ b/shell-completion/bash/systemd-path
@@ -0,0 +1,61 @@
+# systemd-path(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+ return 1
+}
+
+__get_names() {
+ systemd-path | { while IFS=: read -r a b; do echo " $a"; done; }
+}
+
+_systemd_path() {
+ local comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version'
+ [ARG]='--suffix'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --suffix)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ comps=$( __get_names )
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd_path systemd-path
diff --git a/shell-completion/bash/systemd-resolve b/shell-completion/bash/systemd-resolve
new file mode 100644
index 0000000..20d904a
--- /dev/null
+++ b/shell-completion/bash/systemd-resolve
@@ -0,0 +1,80 @@
+# systemd-resolve(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_interfaces(){
+ local name
+ for name in $(cd /sys/class/net && command ls); do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
+}
+
+_systemd-resolve() {
+ local i comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version --no-pager -4 -6
+ --service --openpgp --tlsa --status --statistics
+ --reset-statistics --service-address=no --service-txt=no
+ --cname=no --search=no --legend=no --flush-caches
+ --reset-server-features --revert'
+ [ARG]='-i --interface -p --protocol -t --type -c --class --raw
+ --set-dns --set-domain --set-llmnr --set-mdns --set-dnssec --set-nta'
+ )
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --interface|-i)
+ comps=$( __get_interfaces )
+ ;;
+ --protocol|-p|--type|-t|--class|-c)
+ comps=$( systemd-resolve --legend=no "$prev" help; echo help )
+ ;;
+ --raw)
+ comps="payload packet"
+ ;;
+ --set-dns|--set-domain|--set-nta)
+ comps=""
+ ;;
+ --set-llmnr|--set-mdns)
+ comps="yes no resolve"
+ ;;
+ --set-dnssec)
+ comps="yes no allow-downgrade"
+ ;;
+ --set-dnsovertls)
+ comps="yes no opportunistic"
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]] || [[ -z ${comps-} ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+}
+
+complete -F _systemd-resolve systemd-resolve
diff --git a/shell-completion/bash/systemd-run b/shell-completion/bash/systemd-run
new file mode 100644
index 0000000..c18228d
--- /dev/null
+++ b/shell-completion/bash/systemd-run
@@ -0,0 +1,132 @@
+# systemd-run(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__systemctl() {
+ local mode=$1; shift 1
+ systemctl $mode --full --no-legend --no-pager --plain "$@"
+}
+
+__get_slice_units () { __systemctl $1 list-units --all -t slice \
+ | { while read -r a b c d; do echo " $a"; done; }; }
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+_systemd_run() {
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local OPTS='--no-ask-password --scope -u --unit -p --property --description --slice --slice-inherit
+ -r --remain-after-exit --send-sighup --service-type --uid --gid --nice
+ --working-directory -d --same-dir -E --setenv -t --pty -P --pipe -S --shell -q --quiet
+ --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar
+ --on-clock-change --on-timezone-change --path-property --socket-property
+ --timer-property --no-block --wait -G --collect --user --system -H --host -M --machine
+ -h --help --version'
+
+ local mode=--system
+ local i
+ local opts_with_values=(
+ --unit -p --property --slice --description --service-type --uid --gid --nice --working-directory
+ -E --setenv --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar
+ --path-property --socket-property --timer-property -H --host -M --machine
+ )
+ for (( i=1; i <= COMP_CWORD; i++ )); do
+ if [[ ${COMP_WORDS[i]} != -* ]]; then
+ local root_command=${COMP_WORDS[i]}
+ _command_offset $i
+ return
+ fi
+
+ [[ ${COMP_WORDS[i]} == "--user" ]] && mode=--user
+
+ [[ $i -lt $COMP_CWORD && " ${opts_with_values[@]} " =~ " ${COMP_WORDS[i]} " ]] && ((i++))
+ done
+
+ case "$prev" in
+ --unit|--description|--on-active|--on-boot|--on-startup|--on-unit-active|--on-unit-inactive|--on-calendar)
+ # argument required but no completions available
+ return
+ ;;
+ --slice)
+ local comps=$(__get_slice_units $mode)
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ --service-type)
+ local comps='simple forking oneshot dbus notify idle'
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ -p|--property)
+ local comps='CPUAccounting= MemoryAccounting= BlockIOAccounting= SendSIGHUP=
+ SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group=
+ DevicePolicy= KillMode= ExitType= DeviceAllow= BlockIOReadBandwidth=
+ BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment=
+ KillSignal= RestartKillSignal= FinalKillSignal= LimitCPU= LimitFSIZE= LimitDATA=
+ LimitSTACK= LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC=
+ LimitMEMLOCK= LimitLOCKS= LimitSIGPENDING= LimitMSGQUEUE=
+ LimitNICE= LimitRTPRIO= LimitRTTIME= PrivateTmp= PrivateDevices=
+ PrivateNetwork= NoNewPrivileges= WorkingDirectory= RootDirectory=
+ TTYPath= SyslogIdentifier= SyslogLevelPrefix= SyslogLevel=
+ SyslogFacility= TimerSlackNSec= OOMScoreAdjust= ReadWritePaths=
+ ReadOnlyPaths= InaccessiblePaths= EnvironmentFile=
+ ProtectSystem= ProtectHome= RuntimeDirectory= PassEnvironment='
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ -H|--host)
+ local comps=$(compgen -A hostname)
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ -M|--machine)
+ local comps=$( __get_machines )
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ --timer-property)
+ local comps='AccuracySec= WakeSystem='
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ ;;
+ --working-directory)
+ local comps
+ if [[ -z $cur ]]; then
+ comps=$(compgen -A directory -- "/" )
+ else
+ comps=$(compgen -A directory -- "$cur" )
+ fi
+ compopt -o filenames
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur" ) )
+ return 0
+ ;;
+ esac
+
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd_run systemd-run
diff --git a/shell-completion/bash/systemd-sysext b/shell-completion/bash/systemd-sysext
new file mode 100644
index 0000000..b3f9f32
--- /dev/null
+++ b/shell-completion/bash/systemd-sysext
@@ -0,0 +1,85 @@
+# systemd-sysext(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word() {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+_systemd-sysext() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
+ local -A OPTS=(
+ [STANDALONE]='-h --help --version
+ --no-pager
+ --no-legend
+ --force'
+ [ARG]='--root
+ --json'
+ )
+
+ local -A VERBS=(
+ [STANDALONE]='status
+ merge
+ unmerge
+ refresh
+ list'
+ )
+
+ _init_completion || return
+
+ if __contains_word "$prev" ${OPTS[ARG]}; then
+ case $prev in
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o dirnames
+ ;;
+ --json)
+ comps='pretty short off'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+ return 0
+ fi
+
+ 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[STANDALONE]}; then
+ comps=''
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _systemd-sysext systemd-sysext
diff --git a/shell-completion/bash/timedatectl b/shell-completion/bash/timedatectl
new file mode 100644
index 0000000..768b4a5
--- /dev/null
+++ b/shell-completion/bash/timedatectl
@@ -0,0 +1,97 @@
+# timedatectl(1) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_machines() {
+ local a b
+ { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
+ { while read a b; do echo " $a"; done; } | \
+ sort -u
+}
+
+__get_interfaces(){
+ local name
+ for name in $(cd /sys/class/net && command ls); do
+ [[ "$name" != "lo" ]] && echo "$name"
+ done
+}
+_timedatectl() {
+ local i verb comps
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local OPTS='-h --help --version --adjust-system-clock --no-pager
+ --no-ask-password -H --host -M --machine --monitor
+ -p --property -a --all --value'
+
+ if __contains_word "$prev" $OPTS; then
+ case $prev in
+ --host|-H)
+ comps=$(compgen -A hostname)
+ ;;
+ --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=(
+ [BOOLEAN]='set-local-rtc set-ntp'
+ [STANDALONE]='status show list-timezones timesync-status show-timesync'
+ [TIMEZONES]='set-timezone'
+ [TIME]='set-time'
+ [IFNAME]='ntp-servers revert'
+ )
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ comps=${VERBS[*]}
+ elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
+ comps='true false'
+ elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then
+ comps=$(command timedatectl list-timezones)
+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[TIME]}; then
+ comps=''
+ elif __contains_word "$verb" ${VERBS[TIMEZONES]}; then
+ comps=$( __get_interfaces )
+ fi
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _timedatectl timedatectl
diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm
new file mode 100644
index 0000000..0606160
--- /dev/null
+++ b/shell-completion/bash/udevadm
@@ -0,0 +1,322 @@
+# udevadm(8) completion -*- shell-script -*-
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# 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 <https://www.gnu.org/licenses/>.
+
+__contains_word () {
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+}
+
+__get_all_sysdevs() {
+ local -a devs=(/sys/bus/*/devices/*/ /sys/class/*/*/)
+ printf '%s\n' "${devs[@]%/}"
+}
+
+__get_all_devs() {
+ local i
+ for i in /dev/* /dev/*/* /dev/*/*/*; do
+ echo $i
+ done
+}
+
+__get_all_device_units() {
+ systemctl list-units -t device --full --no-legend --no-pager --plain 2>/dev/null | \
+ { while read -r a b; do echo "$a"; done; }
+}
+
+_udevadm() {
+ local i verb comps builtin
+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+ local -A OPTS=(
+ [COMMON]='-h --help -V --version'
+ [DEBUG]='-d --debug'
+ [INFO_STANDALONE]='-r --root -a --attribute-walk -x --export -e --export-db -c --cleanup-db
+ -w --wait-for-initialization --value'
+ [INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file --property'
+ [TRIGGER_STANDALONE]='-v --verbose -n --dry-run -q --quiet -w --settle --wait-daemon --uuid
+ --initialized-match --initialized-nomatch'
+ [TRIGGER_ARG]='-t --type -c --action -s --subsystem-match -S --subsystem-nomatch
+ -a --attr-match -A --attr-nomatch -p --property-match
+ -g --tag-match -y --sysname-match --name-match -b --parent-match
+ --prioritized-subsystem'
+ [SETTLE]='-t --timeout -E --exit-if-exists'
+ [CONTROL_STANDALONE]='-e --exit -s --stop-exec-queue -S --start-exec-queue -R --reload --ping'
+ [CONTROL_ARG]='-l --log-priority -p --property -m --children-max -t --timeout'
+ [MONITOR_STANDALONE]='-k --kernel -u --udev -p --property'
+ [MONITOR_ARG]='-s --subsystem-match -t --tag-match'
+ [TEST]='-a --action -N --resolve-names'
+ [TEST_BUILTIN]='-a --action'
+ [VERIFY]='-N --resolve-names --root --no-summary --no-style'
+ [WAIT]='-t --timeout --initialized=no --removed --settle'
+ [LOCK]='-t --timeout -d --device -b --backing -p --print'
+ )
+
+ local verbs=(info trigger settle control monitor test-builtin test verify wait lock)
+ local builtins=(blkid btrfs hwdb input_id keyboard kmod net_id net_setup_link path_id usb_id uaccess)
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" "${verbs[@]}"; then
+ verb=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z ${verb-} ]]; then
+ if [[ "$cur" = -* ]]; then
+ COMPREPLY=( $(compgen -W '${OPTS[COMMON]} ${OPTS[DEBUG]}' -- "$cur") )
+ else
+ COMPREPLY=( $(compgen -W '${verbs[*]}' -- "$cur") )
+ fi
+ return 0
+ fi
+
+ case $verb in
+ 'info')
+ if __contains_word "$prev" ${OPTS[INFO_ARG]}; then
+ case $prev in
+ -q|--query)
+ comps='name symlink path property all'
+ ;;
+ -p|--path)
+ comps=$( __get_all_sysdevs )
+ local IFS=$'\n'
+ ;;
+ -n|--name)
+ comps=$( __get_all_devs )
+ ;;
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[INFO_STANDALONE]} ${OPTS[INFO_ARG]}"
+ else
+ comps=$( __get_all_sysdevs; __get_all_device_units )
+ local IFS=$'\n'
+ fi
+ ;;
+
+ 'trigger')
+ if __contains_word "$prev" ${OPTS[TRIGGER_ARG]}; then
+ case $prev in
+ -t|--type)
+ comps='all devices subsystems'
+ ;;
+ -c|--action)
+ comps=$( udevadm trigger --action help )
+ ;;
+ -y|--sysname-match|-b|--parent-match)
+ comps=$( __get_all_sysdevs )
+ local IFS=$'\n'
+ ;;
+ --name-match)
+ comps=$( __get_all_devs )
+ ;;
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[TRIGGER_STANDALONE]} ${OPTS[TRIGGER_ARG]}"
+ else
+ comps=$( __get_all_sysdevs; __get_all_device_units )
+ local IFS=$'\n'
+ fi
+ ;;
+
+ 'settle')
+ if __contains_word "$prev" ${OPTS[SETTLE]}; then
+ case $prev in
+ -E|--exit-if-exists)
+ comps=$( compgen -A file -- "$cur" )
+ ;;
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ comps="${OPTS[COMMON]} ${OPTS[SETTLE]}"
+ ;;
+
+ 'control')
+ if __contains_word "$prev" ${OPTS[CONTROL_ARG]}; then
+ case $prev in
+ -l|--log-priority)
+ comps='alert crit debug emerg err info notice warning'
+ ;;
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ comps="${OPTS[COMMON]} ${OPTS[CONTROL_STANDALONE]} ${OPTS[CONTROL_ARG]}"
+ ;;
+
+ 'monitor')
+ if __contains_word "$prev" ${OPTS[MONITOR_ARG]}; then
+ case $prev in
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ comps="${OPTS[COMMON]} ${OPTS[MONITOR_STANDALONE]} ${OPTS[MONITOR_ARG]}"
+ ;;
+
+ 'test')
+ if __contains_word "$prev" ${OPTS[TEST]}; then
+ case $prev in
+ -a|--action)
+ comps=$( udevadm test --action help )
+ ;;
+ -N|--resolve-names)
+ comps='early late never'
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[TEST]}"
+ else
+ comps=$( __get_all_sysdevs )
+ local IFS=$'\n'
+ fi
+ ;;
+
+ 'test-builtin')
+ if __contains_word "$prev" ${OPTS[TEST_BUILTIN]}; then
+ case $prev in
+ -a|--action)
+ comps=$( udevadm test-builtin --action help )
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ for ((i=0; i < COMP_CWORD; i++)); do
+ if __contains_word "${COMP_WORDS[i]}" "${builtins[@]}"; then
+ builtin=${COMP_WORDS[i]}
+ break
+ fi
+ done
+
+ if [[ -z $builtin ]]; then
+ comps="${builtins[@]}"
+ elif [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[TEST_BUILTIN]}"
+ else
+ comps=$( __get_all_sysdevs )
+ local IFS=$'\n'
+ fi
+ ;;
+
+ 'verify')
+ if __contains_word "$prev" ${OPTS[VERIFY]}; then
+ case $prev in
+ -N|--resolve-names)
+ comps='early never'
+ ;;
+ --root)
+ comps=$(compgen -A directory -- "$cur" )
+ compopt -o dirnames
+ ;;
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[VERIFY]}"
+ else
+ comps=$( compgen -A file -- "$cur" )
+ fi
+ ;;
+
+ 'wait')
+ if __contains_word "$prev" ${OPTS[WAIT]}; then
+ case $prev in
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[WAIT]}"
+ else
+ comps=$( __get_all_devs )
+ local IFS=$'\n'
+ fi
+ ;;
+
+ 'lock')
+ if __contains_word "$prev" ${OPTS[LOCK]}; then
+ case $prev in
+ *)
+ comps=''
+ ;;
+ esac
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+ fi
+
+ if [[ $cur = -* ]]; then
+ comps="${OPTS[COMMON]} ${OPTS[LOCK]}"
+ else
+ comps=''
+ fi
+ ;;
+
+ *)
+ comps=${VERBS[*]}
+ ;;
+ esac
+
+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+ return 0
+}
+
+complete -F _udevadm udevadm