From e3760c2f26ebf2507f2e1f17076bdfb7e3b99206 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 5 Feb 2026 18:04:06 +0900 Subject: [PATCH 1/2] perf(nmcli): reduce uses of the "tail" command --- completions-fallback/nmcli.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/completions-fallback/nmcli.bash b/completions-fallback/nmcli.bash index 835db9924f3..fb16c3c1066 100644 --- a/completions-fallback/nmcli.bash +++ b/completions-fallback/nmcli.bash @@ -6,25 +6,25 @@ _comp_cmd_nmcli__con_id() { _comp_compgen_split -l -- "$(nmcli con list 2>/dev/null | - tail -n +2 | _comp_awk -F ' {2,}' '{print $1}')" + _comp_awk -F ' {2,}' 'NR >= 2 {print $1}')" } _comp_cmd_nmcli__con_uuid() { _comp_compgen_split -- "$(nmcli con list 2>/dev/null | - tail -n +2 | _comp_awk -F ' {2,}' '{print $2}')" + _comp_awk -F ' {2,}' 'NR >= 2 {print $2}')" } _comp_cmd_nmcli__ap_ssid() { _comp_compgen_split -l -- "$(nmcli dev wifi list 2>/dev/null | - tail -n +2 | _comp_awk -F ' {2,}' '{print $1}')" + _comp_awk -F ' {2,}' 'NR >= 2 {print $1}')" } _comp_cmd_nmcli__ap_bssid() { _comp_compgen_split -- "$(nmcli dev wifi list 2>/dev/null | - tail -n +2 | _comp_awk -F ' {2,}' '{print $2}')" + _comp_awk -F ' {2,}' 'NR >= 2 {print $2}')" } _comp_cmd_nmcli() From 994dfde72508061b469b1a702b9d00f0dabb79ff Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 5 Feb 2026 17:53:51 +0900 Subject: [PATCH 2/2] fix: add compatibility wrapper for tail The use of "sed 1d" has been replaced with "tail -n +2" in GitHub PR 1567, but it turned out that "tail" in Solaris 11.3 does not support "tail -n +2", i.e., the POSIX option "-n" [1]. This patch tries to fix up the uses of "tail" by introducing a compatibility wrapper for "tail". Solaris 11.3 provides a POSIX-compatible version of tail through /usr/xpg4/bin/tail in a similar way as the POSIX-compatible version of awk at /usr/xpg4/bin/awk. We add a wrapper for "tail" in the same way as we do for "awk". To avoid aliases and shell functions of the same name, the new wrapper also prefixes "command" to call "tail" in normal environment. The branch that had used "sed 1d" for Solaris is also selected in AIX. This lead to a suspicion that AIX tail might also have a compatibility issue [2]. According to the online manuals, the tail command in AIX (at least >= 5.3) seems to support "-n +N" [3-5]. [1] \ https://github.com/scop/bash-completion/pull/1567#issuecomment-3851588026 [2] \ https://github.com/scop/bash-completion/pull/1567#discussion_r2770809286 [3] AIX 5.3 (2004-08) \ http://public.dhe.ibm.com/systems/power/docs/aix/53/aixcmds5.pdf [4] AIX 6.1 (2007-11) \ http://public.dhe.ibm.com/systems/power/docs/aix/61/aixcmds5_pdf.pdf [5] AIX 7.3.0 (2021-12) \ https://www.ibm.com/docs/en/aix/7.3.0?topic=t-tail-command --- bash_completion | 45 ++++++++++++++++++++----------- completions-core/2to3.bash | 2 +- completions-core/7z.bash | 2 +- completions-core/cowsay.bash | 2 +- completions-core/function.bash | 2 +- completions-core/genisoimage.bash | 2 +- completions-core/mcrypt.bash | 2 +- completions-core/msynctool.bash | 6 ++--- completions-core/pdftotext.bash | 2 +- 9 files changed, 39 insertions(+), 26 deletions(-) diff --git a/bash_completion b/bash_completion index e67cc3d51a4..1c2802bec72 100644 --- a/bash_completion +++ b/bash_completion @@ -2072,12 +2072,12 @@ if [[ $OSTYPE == *@(solaris|aix)* ]]; then # This function completes on process IDs. _comp_compgen_pids() { - _comp_compgen_split -- "$(command ps -efo pid | tail -n +2)" + _comp_compgen_split -- "$(command ps -efo pid | _comp_tail -n +2)" } _comp_compgen_pgids() { - _comp_compgen_split -- "$(command ps -efo pgid | tail -n +2)" + _comp_compgen_split -- "$(command ps -efo pgid | _comp_tail -n +2)" } _comp_compgen_pnames() { @@ -2098,7 +2098,7 @@ else { local -a procs=() if [[ ${1-} == -s ]]; then - _comp_split procs "$(command ps ax -o comm | tail -n +2)" + _comp_split procs "$(command ps ax -o comm | _comp_tail -n +2)" else # Some versions of ps don't support "command", but do "comm", e.g. # some busybox ones. Fall back @@ -3560,20 +3560,33 @@ _comp_xfunc() "$xfunc_name" "${@:3}" } -# Call a POSIX-compatible awk. Solaris awk is not POSIX-compliant, but Solaris -# provides a POSIX-compatible version through /usr/xpg4/bin/awk. We switch the -# implementation to /usr/xpg4/bin/awk in Solaris if any. +# Call a POSIX-compatible awk and tail. Solaris awk and tail are not +# POSIX-compliant, but Solaris provides POSIX-compatible versions through +# /usr/xpg4/bin/{awk,tail}. We switch the implementation to +# /usr/xpg4/bin/{awk,tail} in Solaris if any. # @since 2.12 -if [[ $OSTYPE == *solaris* && -x /usr/xpg4/bin/awk ]]; then - _comp_awk() - { - /usr/xpg4/bin/awk "$@" - } -else - _comp_awk() - { - command awk "$@" - } +_comp_awk() +{ + command awk "$@" +} +# @since 2.18 +_comp_tail() +{ + command tail "$@" +} +if [[ $OSTYPE == *solaris* ]]; then + if [[ -x /usr/xpg4/bin/awk ]]; then + _comp_awk() + { + /usr/xpg4/bin/awk "$@" + } + fi + if [[ -x /usr/xpg4/bin/tail ]]; then + _comp_tail() + { + /usr/xpg4/bin/tail "$@" + } + fi fi # List custom/extra completion files to source on the startup diff --git a/completions-core/2to3.bash b/completions-core/2to3.bash index a75abad575f..27c1c538bb1 100644 --- a/completions-core/2to3.bash +++ b/completions-core/2to3.bash @@ -11,7 +11,7 @@ _comp_cmd_2to3() ;; -f | --fix | -x | --nofix) _comp_compgen_split -- "$( - "$1" --list-fixes 2>/dev/null | tail -n +2 + "$1" --list-fixes 2>/dev/null | _comp_tail -n +2 )" return ;; diff --git a/completions-core/7z.bash b/completions-core/7z.bash index bcc6870ee13..c8d31920c88 100644 --- a/completions-core/7z.bash +++ b/completions-core/7z.bash @@ -99,7 +99,7 @@ _comp_cmd_7z() if [[ ${words[1]} == d ]]; then _comp_compgen_split -l -- "$( "$1" l "${words[2]}" -slt 2>/dev/null | command sed -n \ - 's/^Path = \(.*\)$/\1/p' 2>/dev/null | tail -n+2 + 's/^Path = \(.*\)$/\1/p' 2>/dev/null | _comp_tail -n +2 )" compopt -o filenames else diff --git a/completions-core/cowsay.bash b/completions-core/cowsay.bash index ea1468caf5b..dd2f3bdefdc 100644 --- a/completions-core/cowsay.bash +++ b/completions-core/cowsay.bash @@ -7,7 +7,7 @@ _comp_cmd_cowsay() case $prev in -f) - _comp_compgen_split -- "$(cowsay -l 2>/dev/null | tail -n +2)" + _comp_compgen_split -- "$(cowsay -l 2>/dev/null | _comp_tail -n +2)" return ;; esac diff --git a/completions-core/function.bash b/completions-core/function.bash index ba8d725109a..6d064d4e850 100644 --- a/completions-core/function.bash +++ b/completions-core/function.bash @@ -8,7 +8,7 @@ _comp_cmd_function() if ((cword == 1)); then _comp_compgen -- -A function else - local funcdef=$(type -- "${words[1]}" 2>/dev/null | tail -n +3) + local funcdef=$(type -- "${words[1]}" 2>/dev/null | _comp_tail -n +3) COMPREPLY=("()${funcdef:+ $funcdef}") fi } && diff --git a/completions-core/genisoimage.bash b/completions-core/genisoimage.bash index d54fdf67ef6..19df78a2d78 100644 --- a/completions-core/genisoimage.bash +++ b/completions-core/genisoimage.bash @@ -13,7 +13,7 @@ _comp_cmd_mkisofs() ;; -*-charset) _comp_compgen_split -- "$(mkisofs -input-charset help 2>&1 | - tail -n +3)" + _comp_tail -n +3)" return ;; -uid) diff --git a/completions-core/mcrypt.bash b/completions-core/mcrypt.bash index 2c8595eb88f..aea894096a1 100644 --- a/completions-core/mcrypt.bash +++ b/completions-core/mcrypt.bash @@ -26,7 +26,7 @@ _comp_cmd_mcrypt() ;; -h | --hash) _comp_compgen_split -- "$("$1" --list-hash 2>/dev/null | - tail -n +2)" + _comp_tail -n +2)" return ;; -k | -s | --key | --keysize) diff --git a/completions-core/msynctool.bash b/completions-core/msynctool.bash index e40ba91396f..e626c315391 100644 --- a/completions-core/msynctool.bash +++ b/completions-core/msynctool.bash @@ -12,18 +12,18 @@ _comp_cmd_msynctool() return ;; --addmember) - _comp_compgen_split -- "$("$1" --listplugins | tail -n +2)" + _comp_compgen_split -- "$("$1" --listplugins | _comp_tail -n +2)" return ;; esac case $prev in --configure | --addgroup | --delgroup | --showgroup | --sync | --addmember) - _comp_compgen_split -- "$("$1" --listgroups | tail -n +2)" + _comp_compgen_split -- "$("$1" --listgroups | _comp_tail -n +2)" return ;; --showformats | --filter-objtype | --slow-sync) - _comp_compgen_split -- "$("$1" --listobjects | tail -n +2)" + _comp_compgen_split -- "$("$1" --listobjects | _comp_tail -n +2)" return ;; esac diff --git a/completions-core/pdftotext.bash b/completions-core/pdftotext.bash index 5d7acba52a4..45bba13de4c 100644 --- a/completions-core/pdftotext.bash +++ b/completions-core/pdftotext.bash @@ -11,7 +11,7 @@ _comp_cmd_pdftotext() return ;; -enc) - _comp_compgen_split -- "$("$1" -listenc 2>/dev/null | tail -n +2)" + _comp_compgen_split -- "$("$1" -listenc 2>/dev/null | _comp_tail -n +2)" return ;; -eol)