From f69a63c10fb57e1be57f6505ee1f7e8db27652b4 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 25 Jan 2026 21:52:01 +0900 Subject: [PATCH 1/4] refactor({invoke,update}-rc.d): use "_comp_compgen -C" --- completions-core/invoke-rc.d.bash | 6 +++--- completions-core/update-rc.d.bash | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/completions-core/invoke-rc.d.bash b/completions-core/invoke-rc.d.bash index da3209968aa..1c70a89ca8c 100644 --- a/completions-core/invoke-rc.d.bash +++ b/completions-core/invoke-rc.d.bash @@ -7,7 +7,7 @@ _comp_cmd_invoke_rc_d() local cur prev words cword comp_args _comp_initialize -- "$@" || return - local sysvdir services options + local sysvdir options [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d @@ -25,8 +25,8 @@ _comp_cmd_invoke_rc_d() command grep -E -e "$regex_options" | sort | uniq -u )" - _comp_expand_glob services '"$sysvdir"/!(README*|*.sh|$_comp_backup_glob)' && - _comp_compgen -a -- -W '"${services[@]#"$sysvdir"/}"' + # shellcheck disable=SC2154 + _comp_compgen -aC "$sysvdir" -- -f -X "@(README*|*.sh|$_comp_backup_glob)" elif [[ -x $sysvdir/$prev ]]; then _comp_compgen_split -- "$(command sed -e 'y/|/ /' \ -ne 's/^.*Usage:[ ]*[^ ]*[ ]*{*\([^}"]*\).*$/\1/p' \ diff --git a/completions-core/update-rc.d.bash b/completions-core/update-rc.d.bash index a5040d44724..e45d521d3ca 100644 --- a/completions-core/update-rc.d.bash +++ b/completions-core/update-rc.d.bash @@ -12,8 +12,8 @@ _comp_cmd_update_rc_d() [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d || sysvdir=/etc/init.d - _comp_expand_glob services '"$sysvdir"/!(README*|*.sh|$_comp_backup_glob)' && - services=("${services[@]#$sysvdir/}") + # shellcheck disable=SC2154 + _comp_compgen -v services -C "$sysvdir" -- -f -X "@(README*|*.sh|$_comp_backup_glob)" options=(-f -n) if [[ $cword -eq 1 || $prev == -* ]]; then From e84c2ad21b1efca0f4b4a71e9f1b07bfce80931a Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 25 Jan 2026 21:40:20 +0900 Subject: [PATCH 2/4] refactor(_comp_compgen_services): use "_comp_compgen -C" --- bash_completion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bash_completion b/bash_completion index ebd8eef26a2..f7ddb3e2217 100644 --- a/bash_completion +++ b/bash_completion @@ -2201,7 +2201,7 @@ _comp_compgen_services() _comp_sysvdirs || return 1 local services - _comp_expand_glob services '${sysvdirs[0]}/!($_comp_backup_glob|functions|README)' + _comp_compgen -v services -C "${sysvdirs[0]}" -- -f -X "@($_comp_backup_glob|functions|README)" local _generated=$({ systemctl list-units --full --all || @@ -2215,7 +2215,7 @@ _comp_compgen_services() fi ((${#services[@]})) || return 1 - _comp_compgen -U services -U sysvdirs -- -W '"${services[@]#${sysvdirs[0]}/}"' + _comp_compgen -U services -U sysvdirs -- -W '"${services[@]}"' } # This completes on a list of all available service scripts for the From 2a336e10b9d78df40b77fbc8dc05118066d65d8b Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 25 Jan 2026 21:37:43 +0900 Subject: [PATCH 3/4] refactor(_comp_compgen_services): write to the target directly --- bash_completion | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bash_completion b/bash_completion index f7ddb3e2217..e3a78189e98 100644 --- a/bash_completion +++ b/bash_completion @@ -2194,28 +2194,30 @@ _comp_compgen_xinetd_services() # This function completes on services # +# @return 0 if at least one completion is generated, or 1 otherwise. # @since 2.12 _comp_compgen_services() { local sysvdirs _comp_sysvdirs || return 1 - local services - _comp_compgen -v services -C "${sysvdirs[0]}" -- -f -X "@($_comp_backup_glob|functions|README)" + local status=1 + _comp_compgen -U sysvdirs -C "${sysvdirs[0]}" -- -f -X "@($_comp_backup_glob|functions|README)" && + status=0 local _generated=$({ systemctl list-units --full --all || systemctl list-unit-files } 2>/dev/null | _comp_awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }') - _comp_split -la services "$_generated" + _comp_compgen -a split -l -- "$_generated" && status=0 if [[ -x /sbin/upstart-udev-bridge ]]; then - _comp_split -la services "$(initctl list 2>/dev/null | cut -d' ' -f1)" + _comp_compgen -a split -l -- "$(initctl list 2>/dev/null | cut -d' ' -f1)" && + status=0 fi - ((${#services[@]})) || return 1 - _comp_compgen -U services -U sysvdirs -- -W '"${services[@]}"' + return "$status" } # This completes on a list of all available service scripts for the From b1000f2af35ccacd2a9244dc571e4c96d6d2c941 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 25 Jan 2026 21:54:42 +0900 Subject: [PATCH 4/4] fix(_comp_compgen_services): skip service status marks Recent versions of systemctl seems to prefix a character representing the status before the unit names. Thus, in addition to $1, $2 may also contain a service name. --- bash_completion | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bash_completion b/bash_completion index e3a78189e98..b58d79f930e 100644 --- a/bash_completion +++ b/bash_completion @@ -2208,8 +2208,13 @@ _comp_compgen_services() local _generated=$({ systemctl list-units --full --all || systemctl list-unit-files - } 2>/dev/null | - _comp_awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }') + } 2>/dev/null | _comp_awk ' + # Example output from systemctl: + # httpd.service loaded active running The Apache HTTP Server + # * iptables.service not-found inactive dead iptables.service + sub(/\.service$/, "", $1) { print $1; next } + sub(/\.service$/, "", $2) { print $2 } + ') _comp_compgen -a split -l -- "$_generated" && status=0 if [[ -x /sbin/upstart-udev-bridge ]]; then