[Bash-completion-devel] bash completion fails if shopt "nullglob" is set, repro info follows
C. Alex. North-Keys
erlkonig at talisman.org
Tue Dec 20 10:49:57 UTC 2011
Bash autocompletions fails in many case when "shopt -s nullglob" has
been run.
User visibility:
Anyone using shopt -s nullglob, the entire autocompletion is horribly
broken, essentially useless in many contexts, along with the resulting
frustration. X users sometimes are shielded from the problem if the
subshells spawned in xterms - which aren't login shells - are skipping
the read of /etc/bash_completion .
Reproduction:
root at yggdrasil:~# cd ; mkdir tmp && cd tmp && touch aa bb cc
root at yggdrasil:~/tmp# less bb ^C
root at yggdrasil:~/tmp# # input was "less b<tab>", autocompleted,
"<control-c>"
root at yggdrasil:~/tmp# shopt -s nullglob
root at yggdrasil:~/tmp# less b
aa bb cc
root at yggdrasil:~/tmp# # input was "less b<tab><tab>", autocompletion failed.
Running a trace with set -x shows trouble in
__reassemble_comp_words_by_ref for starters, a function from
/etc/bash_completion, which crumbles fairly early, to wit:
with shopt -u nullglob:
+ _get_comp_words_by_ref -n = cur prev
+ local exclude flag i OPTIND=1
+ words=()
+ local cur cword words
+ upargs=()
+ upvars=()
+ local upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: flag -n = cur prev
+ case $flag in
+ exclude==
+ getopts c:i:n:p:w: flag -n = cur prev
+ [[ 4 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ let 'OPTIND += 1'
+ [[ 4 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 4 -ge 5 ]]
+ __get_cword_at_cursor_by_ref = words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref = words cword
+ local exclude i j ref
+ [[ -n = ]]
+ exclude==
+ eval cword=1
++ cword=1
+ [[ -n = ]]
+ (( i=0, j=0 ))
+ (( i < 2 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
with shopt -u nullglob it continues with:
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=less
+ [[ 0 == 1 ]]
but with shopt -s nullglob we see:
+ eval
+ [[ 0 == 1 ]]
the source is in /etc/bash_completion
309 done
310 # Append word to current word
311 ref="$2[$j]"
> 312 eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
313 # Indicate new cword
314 [[ $i == $COMP_CWORD ]] && eval $3=$j
At this point, on the second iteration of the surrounding loop, $2 ==
words, $j == 0, and words[0] == less (if nullglob is off) or is unset
(if nullglob is on).
More information about the Bash-completion-devel
mailing list