Skip to content

Commit 76b7925

Browse files
committed
fix(nounset): fix nounset errors of -W '${COMPRELY[@]}'
In Bash 4.3, "${arr[@]}" for an empty array "arr=()" fails under the setting "set -o nounset". This causes error messages with "compgen -W '${COMPREPLY[@]}'". In this commit, we check that COMPREPLY is non-empty before trying to call "compgen -W".
1 parent a53a81e commit 76b7925

30 files changed

+126
-77
lines changed

bash_completion

+49-36
Original file line numberDiff line numberDiff line change
@@ -718,15 +718,17 @@ _comp_delimited()
718718
# delimiter so we get space appended.
719719
[[ ! $cur || $cur == *"$delimiter" ]] || unset "existing[${#existing[@]}-1]"
720720
IFS=$ifs
721-
for x in ${existing+"${existing[@]}"}; do
722-
for i in "${!COMPREPLY[@]}"; do
723-
if [[ $x == "${COMPREPLY[i]}" ]]; then
724-
unset "COMPREPLY[i]"
725-
continue 2 # assume no dupes in COMPREPLY
726-
fi
721+
if ((${#COMPREPLY[@]})); then
722+
for x in ${existing+"${existing[@]}"}; do
723+
for i in "${!COMPREPLY[@]}"; do
724+
if [[ $x == "${COMPREPLY[i]}" ]]; then
725+
unset "COMPREPLY[i]"
726+
continue 2 # assume no dupes in COMPREPLY
727+
fi
728+
done
727729
done
728-
done
729-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "${cur##*$delimiter}"))
730+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "${cur##*$delimiter}"))
731+
fi
730732
else
731733
COMPREPLY=($(compgen "$@" -- "${cur##*$delimiter}"))
732734
fi
@@ -760,16 +762,18 @@ _comp_variable_assignments()
760762
TZ)
761763
cur=/usr/share/zoneinfo/$cur
762764
_filedir
763-
for i in "${!COMPREPLY[@]}"; do
764-
if [[ ${COMPREPLY[i]} == *.tab ]]; then
765-
unset 'COMPREPLY[i]'
766-
continue
767-
elif [[ -d ${COMPREPLY[i]} ]]; then
768-
COMPREPLY[i]+=/
769-
compopt -o nospace
770-
fi
771-
COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
772-
done
765+
if ((${#COMPREPLY[@]})); then
766+
for i in "${!COMPREPLY[@]}"; do
767+
if [[ ${COMPREPLY[i]} == *.tab ]]; then
768+
unset 'COMPREPLY[i]'
769+
continue
770+
elif [[ -d ${COMPREPLY[i]} ]]; then
771+
COMPREPLY[i]+=/
772+
compopt -o nospace
773+
fi
774+
COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
775+
done
776+
fi
773777
;;
774778
TERM)
775779
_terms
@@ -1036,7 +1040,8 @@ _mac_addresses()
10361040
COMPREPLY+=($(command sed -ne \
10371041
"s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null))
10381042

1039-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
1043+
((${#COMPREPLY[@]})) &&
1044+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
10401045
__ltrim_colon_completions "$cur"
10411046
}
10421047

@@ -1115,7 +1120,8 @@ _available_interfaces()
11151120
} 2>/dev/null | awk \
11161121
'/^[^ \t]/ { if ($1 ~ /^[0-9]+:/) { print $2 } else { print $1 } }'))
11171122

1118-
COMPREPLY=($(compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur"))
1123+
((${#COMPREPLY[@]})) &&
1124+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]/%[[:punct:]]/}"' -- "$cur"))
11191125
}
11201126

11211127
# Echo number of CPUs, falling back to 1 on failure.
@@ -1345,7 +1351,8 @@ _services()
13451351
COMPREPLY+=($(initctl list 2>/dev/null | cut -d' ' -f1))
13461352
fi
13471353

1348-
COMPREPLY=($(compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur"))
1354+
((${#COMPREPLY[@]})) &&
1355+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]#${sysvdirs[0]}/}"' -- "$cur"))
13491356
}
13501357

13511358
# This completes on a list of all available service scripts for the
@@ -1424,7 +1431,8 @@ _usergroup()
14241431
local IFS=$'\n'
14251432
COMPREPLY=($(compgen -g -- "$mycur"))
14261433
fi
1427-
COMPREPLY=($(compgen -P "$prefix" -W "${COMPREPLY[@]}"))
1434+
((${#COMPREPLY[@]})) &&
1435+
COMPREPLY=($(compgen -P "$prefix" -W '"${COMPREPLY[@]}"'))
14281436
elif [[ $cur == *:* ]]; then
14291437
# Completing group after 'user:gr<TAB>'.
14301438
# Reply with a list of unprefixed groups since readline with split on :
@@ -1844,7 +1852,8 @@ _known_hosts_real()
18441852
IFS=$ifs
18451853
done <"$i"
18461854
done
1847-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
1855+
((${#COMPREPLY[@]})) &&
1856+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
18481857
fi
18491858
if ((${#khd[@]} > 0)); then
18501859
# Needs to look for files called
@@ -1861,9 +1870,11 @@ _known_hosts_real()
18611870
fi
18621871

18631872
# apply suffix and prefix
1864-
for i in ${!COMPREPLY[*]}; do
1865-
COMPREPLY[i]=$prefix${COMPREPLY[i]}$suffix
1866-
done
1873+
if ((${#COMPREPLY[@]})); then
1874+
for i in ${!COMPREPLY[*]}; do
1875+
COMPREPLY[i]=$prefix${COMPREPLY[i]}$suffix
1876+
done
1877+
fi
18671878
fi
18681879

18691880
# append any available aliases from ssh config files
@@ -1903,16 +1914,18 @@ _known_hosts_real()
19031914
IFS=$' \t\n'
19041915
$reset
19051916

1906-
if [[ -v ipv4 ]]; then
1907-
COMPREPLY=("${COMPREPLY[@]/*:*$suffix/}")
1908-
fi
1909-
if [[ -v ipv6 ]]; then
1910-
COMPREPLY=("${COMPREPLY[@]/+([0-9]).+([0-9]).+([0-9]).+([0-9])$suffix/}")
1911-
fi
1912-
if [[ -v ipv4 || -v ipv6 ]]; then
1913-
for i in "${!COMPREPLY[@]}"; do
1914-
[[ ${COMPREPLY[i]} ]] || unset -v "COMPREPLY[i]"
1915-
done
1917+
if ((${#COMPREPLY[@]})); then
1918+
if [[ -v ipv4 ]]; then
1919+
COMPREPLY=("${COMPREPLY[@]/*:*$suffix/}")
1920+
fi
1921+
if [[ -v ipv6 ]]; then
1922+
COMPREPLY=("${COMPREPLY[@]/+([0-9]).+([0-9]).+([0-9]).+([0-9])$suffix/}")
1923+
fi
1924+
if [[ -v ipv4 || -v ipv6 ]]; then
1925+
for i in "${!COMPREPLY[@]}"; do
1926+
[[ ${COMPREPLY[i]} ]] || unset -v "COMPREPLY[i]"
1927+
done
1928+
fi
19161929
fi
19171930

19181931
__ltrim_colon_completions "$prefix$cur"

completions/_rtcwake

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ _rtcwake()
1818
;;
1919
--device | -d)
2020
COMPREPLY=($(command ls -d /dev/rtc?* 2>/dev/null))
21-
COMPREPLY=($(compgen -W '${COMPREPLY[@]#/dev/}' -- "$cur"))
21+
((${#COMPREPLY[@]})) &&
22+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]#/dev/}"' -- "$cur"))
2223
return
2324
;;
2425
esac

completions/aptitude

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ _aptitude()
104104
esac
105105
done
106106

107-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
107+
((${#COMPREPLY[@]})) &&
108+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
108109
else
109110
COMPREPLY=($(compgen -W 'update upgrade safe-upgrade forget-new
110111
clean autoclean install reinstall remove hold unhold purge markauto

completions/aspell

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ _aspell_dictionary()
66
datadir=$($aspell config data-dir 2>/dev/null || echo /usr/lib/aspell)
77
# First, get aliases (dicts dump does not list them)
88
COMPREPLY=($datadir/*.alias)
9-
COMPREPLY=("${COMPREPLY[@]%.alias}")
10-
COMPREPLY=("${COMPREPLY[@]#$datadir/}")
9+
if ((${#COMPREPLY[@]})); then
10+
COMPREPLY=("${COMPREPLY[@]%.alias}")
11+
COMPREPLY=("${COMPREPLY[@]#$datadir/}")
12+
fi
1113
# Then, add the canonical dicts
1214
COMPREPLY+=($($aspell dicts 2>/dev/null))
13-
COMPREPLY=($(compgen -X '\*' -W '${COMPREPLY[@]}' -- "$cur"))
15+
((${#COMPREPLY[@]})) &&
16+
COMPREPLY=($(compgen -X '\*' -W '"${COMPREPLY[@]}"' -- "$cur"))
1417
}
1518

1619
_aspell()

completions/complete

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ _complete()
3030
;;
3131
-*p | -*r)
3232
COMPREPLY=($(complete -p | command sed -e 's|.* ||'))
33-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
33+
((${#COMPREPLY[@]})) &&
34+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
3435
return
3536
;;
3637
esac

completions/curl

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ _curl()
7171
;;
7272
--dns-servers | --noproxy)
7373
_known_hosts_real -- "${cur##*,}"
74-
_comp_delimited , -W '${COMPREPLY[@]}'
74+
((${#COMPREPLY[@]})) &&
75+
_comp_delimited , -W '"${COMPREPLY[@]}"'
7576
return
7677
;;
7778
--engine)

completions/cvs

+7-3
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ _cvs()
226226
[[ ! -v cvsroot ]] && cvsroot=${CVSROOT-}
227227
COMPREPLY=($(cvs -d "$cvsroot" co -c 2>/dev/null |
228228
awk '{print $1}'))
229-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
229+
((${#COMPREPLY[@]})) &&
230+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
230231
else
231232
_cvs_command_options "$1" $mode
232233
fi
@@ -304,7 +305,8 @@ _cvs()
304305
if [[ $cur != -* ]]; then
305306
[[ ! -v cvsroot ]] && cvsroot=${CVSROOT-}
306307
COMPREPLY=($(cvs -d "$cvsroot" co -c | awk '{print $1}'))
307-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
308+
((${#COMPREPLY[@]})) &&
309+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
308310
else
309311
_cvs_command_options "$1" $mode
310312
fi
@@ -332,7 +334,9 @@ _cvs()
332334
fi
333335
pwd=$(pwd)
334336
pwd=${pwd##*/}
335-
COMPREPLY=($(compgen -W '${COMPREPLY[@]} $pwd' -- "$cur"))
337+
[[ $pwd ]] && COMPREPLY+=("$pwd")
338+
((${#COMPREPLY[@]})) &&
339+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
336340
else
337341
_cvs_command_options "$1" $mode
338342
fi

completions/dot

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ _dot()
2626
-o*)
2727
cur=${cur#-o}
2828
_filedir
29-
COMPREPLY=($(compgen -P -o -W '${COMPREPLY[@]}' -- "$cur"))
29+
((${#COMPREPLY[@]})) &&
30+
COMPREPLY=($(compgen -P -o -W '"${COMPREPLY[@]}"' -- "$cur"))
3031
return
3132
;;
3233
esac

completions/hcitool

+3-2
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,9 @@ _hciattach()
355355
case $args in
356356
1)
357357
COMPREPLY=(/dev/tty*)
358-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}
359-
${COMPREPLY[@]#/dev/}' -- "$cur"))
358+
((${#COMPREPLY[@]})) &&
359+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"
360+
"${COMPREPLY[@]#/dev/}"' -- "$cur"))
360361
;;
361362
2)
362363
COMPREPLY=($(compgen -W 'any ericsson digi xircom csr bboxes

completions/ifup

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ _ifupdown()
3131

3232
if ((args == 1)); then
3333
_configured_interfaces
34-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
34+
((${#COMPREPLY[@]})) &&
35+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
3536
fi
3637
} &&
3738
complete -F _ifupdown ifup ifdown ifquery ifstatus

completions/info

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ _info()
6666
done
6767
# strip suffix from info pages
6868
COMPREPLY=(${COMPREPLY[@]%.@(gz|bz2|xz|lzma)})
69-
COMPREPLY=($(compgen -W '${COMPREPLY[@]%.*}' -- "${cur//\\\\/}"))
69+
((${#COMPREPLY[@]})) &&
70+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]%.*}"' -- "${cur//\\\\/}"))
7071

7172
} &&
7273
complete -F _info info pinfo

completions/ip

+4-3
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@ _ip()
314314
show)
315315
if [[ $cword -eq $subcword+1 || $prev == dev ]]; then
316316
_available_interfaces
317-
[[ $prev != dev ]] &&
318-
COMPREPLY=($(compgen -W '${COMPREPLY[@]} dev' \
319-
-- "$cur"))
317+
if [[ $prev != dev ]]; then
318+
COMPREPLY+=(dev)
319+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
320+
fi
320321
fi
321322
;;
322323
*)

completions/ipsec

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ _ipsec_connections()
1010
if [[ $keyword == [#]* ]]; then continue; fi
1111
[[ $keyword == conn && $name != '%default' ]] && COMPREPLY+=("$name")
1212
done
13-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
13+
((${#COMPREPLY[@]})) &&
14+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
1415
}
1516

1617
_ipsec_freeswan()

completions/man

+4-2
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ _man()
8484
# weed out directory path names and paths to man pages
8585
COMPREPLY=(${COMPREPLY[@]##*/?(:)})
8686
# strip suffix from man pages
87-
COMPREPLY=(${COMPREPLY[@]%$comprsuffix})
88-
COMPREPLY=($(compgen -W '${COMPREPLY[@]%.*}' -- "${cur//\\\\/}"))
87+
((${#COMPREPLY[@]})) &&
88+
COMPREPLY=(${COMPREPLY[@]%$comprsuffix})
89+
((${#COMPREPLY[@]})) &&
90+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]%.*}"' -- "${cur//\\\\/}"))
8991
fi
9092

9193
# shellcheck disable=SC2053

completions/minicom

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ _minicom()
1616
;;
1717
--ptty | -!(-*)p)
1818
COMPREPLY=(/dev/tty*)
19-
COMPREPLY=($(compgen -W '${COMPREPLY[@]} ${COMPREPLY[@]#/dev/}' \
20-
-- "$cur"))
19+
((${#COMPREPLY[@]})) &&
20+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}" "${COMPREPLY[@]#/dev/}}' \
21+
-- "$cur"))
2122
return
2223
;;
2324
esac

completions/pgrep

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ _pgrep()
3939
command sed -ne \
4040
"s/^[[:space:]]*Available namespaces://p")' \
4141
-- "${cur##*,}"))
42-
_comp_delimited , -W '${COMPREPLY[@]}'
42+
((${#COMPREPLY[@]})) &&
43+
_comp_delimited , -W '"${COMPREPLY[@]}"'
4344
return
4445
;;
4546
esac

completions/ps

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ _comp_cmd_ps()
4343
shopt -s nullglob
4444
printf '%s\n' /dev/tty*
4545
))
46-
COMPREPLY=($(compgen -W '${COMPREPLY[@]} ${COMPREPLY[@]#/dev/}' \
47-
-- "$cur"))
46+
((${#COMPREPLY[@]})) &&
47+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}" "${COMPREPLY[@]#/dev/}"' \
48+
-- "$cur"))
4849
return
4950
;;
5051
?(-)U | [^-]*U | -u | --[Uu]ser)

completions/pylint

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ _pylint()
4343
;;
4444
--load-plugins | --deprecated-modules)
4545
cur="${cur##*,}" _xfunc python _python_modules $python
46-
_comp_delimited , -W '${COMPREPLY[@]}'
46+
((${#COMPREPLY[@]})) &&
47+
_comp_delimited , -W '"${COMPREPLY[@]}"'
4748
return
4849
;;
4950
--jobs | -!(-*)j)

completions/pytest

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ _pytest()
115115
fi
116116
done 2>/dev/null <"$file"
117117
((!${#COMPREPLY[@]})) ||
118-
COMPREPLY=($(compgen -P "$file::$class::" -W '${COMPREPLY[@]}' \
118+
COMPREPLY=($(compgen -P "$file::$class::" -W '"${COMPREPLY[@]}"' \
119119
-- "${cur##*:?(:)}"))
120120
__ltrim_colon_completions "$cur"
121121
return
@@ -129,7 +129,7 @@ _pytest()
129129
fi
130130
done 2>/dev/null <"$file"
131131
((!${#COMPREPLY[@]})) ||
132-
COMPREPLY=($(compgen -P "$file::" -W '${COMPREPLY[@]}' \
132+
COMPREPLY=($(compgen -P "$file::" -W '"${COMPREPLY[@]}"' \
133133
-- "${cur##*.py:?(:)}"))
134134
__ltrim_colon_completions "$cur"
135135
return

completions/rdesktop

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ _rdesktop()
1212
command grep -E -v '(common|modifiers)'))
1313
COMPREPLY+=($(command ls $HOME/.rdesktop/keymaps 2>/dev/null))
1414
COMPREPLY+=($(command ls ./keymaps 2>/dev/null))
15-
COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur"))
15+
((${#COMPREPLY[@]})) &&
16+
COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur"))
1617
return
1718
;;
1819
-*a)

completions/ri

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ _ri_get_methods()
2828
print $_.split(/, |,$| +/).grep(/^[^\[]*$/).join("\n"); \
2929
end' | sort -u)")
3030
fi
31-
COMPREPLY=($(compgen $prefix -W '${COMPREPLY[@]}' -- $method))
31+
((${#COMPREPLY[@]})) &&
32+
COMPREPLY=($(compgen $prefix -W '"${COMPREPLY[@]}"' -- $method))
3233
}
3334

3435
# needs at least Ruby 1.8.0 in order to use -W0

0 commit comments

Comments
 (0)