# shellcheck shell=bash # 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 . __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_device_nodes() { 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; } } __get_all_devices() { __get_all_sysdevs __get_all_device_nodes __get_all_device_units } _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 -t --tree -x --export -e --export-db -c --cleanup-db -w --wait-for-initialization --value --no-pager --initialized-match --initialized-nomatch' [INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file --property --json --subsystem-match --subsystem-nomatch --attr-match --attr-nomatch --property-match --tag-match --sysname-match --name-match --parent-match' [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 --load-credentials' [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_device_nodes ) ;; --json) comps=$( udevadm info --json=help ) ;; --parent-match) comps=$( __get_all_sysdevs ) local IFS=$'\n' ;; --name-match) comps=$( __get_all_device_nodes ) ;; *) 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_devices ) 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_device_nodes ) ;; *) 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_devices ) 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_devices ) 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_devices ) 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_devices ) 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