Open calestyo opened 3 years ago
Thanks for the report. Please follow instructions in the bug report template -- this does not happen for me nor in CI, load time debug trace is needed to diagnose further.
I'm guessing that the trace will reveal that the errors come from completions not included with bash-completion but some 3rd party ones, per the above, and because there is no variable named filenames
in the bash-completion source tree that I can see.
Hey again.
This time I might have found a real occasion ;-)
If I have set -u and a command like:
find ../new/ -type f -printf '%f\n' | while IFS='' read -r FILENAME; do printf 'ln -s /dev/nu %q\n' "${FILENAME}" ; done | sh
now when I go to the /dev/nu
and complete it with tab to /dev/null I get:
../new/ -type f -printf '%f\n' | while IFS='' read -r FILENAME; do printf 'ln -s /dev/nubash: COMP_WORDS[i]: unbound variable
This seems to happen in:
+ offset=1
+ (( i = 1 ))
+ (( i <= COMP_CWORD ))
+ [[ printf != -* ]]
+ offset=1
+ break
+ _command_offset 1
+ local word_offset=1 i j
+ (( i = 0 ))
+ (( i < word_offset ))
+ (( j = 0 ))
+ (( j <= 55 ))
+ [[ do printf 'ln -s /dev/n %q\n' "${FILENAME}" ; done | sh == \d\o* ]]
+ break
+ COMP_LINE=' printf '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( COMP_POINT -= 2 ))
+ (( i++ ))
+ (( i < word_offset ))
+ (( i = 0 ))
+ (( i <= COMP_CWORD - word_offset ))
+ COMP_WORDS[i]=printf
+ (( i++ ))
+ (( i <= COMP_CWORD - word_offset ))
+ COMP_WORDS[i]=''\''ln -s /dev/n %q\n'\'''
+ (( i++ ))
+ (( i <= COMP_CWORD - word_offset ))
+ (( i ))
+ (( i <= COMP_CWORD ))
+ unset 'COMP_WORDS[i]'
+ (( i++ ))
+ (( i <= COMP_CWORD ))
+ (( COMP_CWORD -= word_offset ))
+ COMPREPLY=()
+ local cur
+ _get_comp_words_by_ref cur
+ 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 cur
+ [[ 1 -ge 1 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ (( OPTIND += 1 ))
+ [[ 1 -ge 2 ]]
+ __get_cword_at_cursor_by_ref '' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '' words cword
+ local exclude i j line ref
+ [[ -n '' ]]
+ printf -v cword %s 1
+ [[ -v exclude ]]
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s printf
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s ''\''ln -s /dev/n %q\n'\'''
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s '"${FILENAME}"'
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s ';'
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s done
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s '|'
+ for i in "${!COMP_WORDS[@]}"
+ printf -v 'words[i]' %s sh
+ local i cur= index=21 'lead= printf '\''ln -s /dev/n'
+ [[ 21 -gt 0 ]]
+ [[ -n printf 'ln -s /dev/n ]]
+ [[ -n printf'ln-s/dev/n ]]
+ cur=' printf '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 53 -ge 6 ]]
+ [[ print != \p\r\i\n\t\f ]]
+ cur='printf '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( index > 0 ))
+ (( index-- ))
+ [[ 52 -ge 6 ]]
+ [[ printf != \p\r\i\n\t\f ]]
+ (( i < cword ))
+ local old_size=52
+ cur=' '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ local new_size=46
+ (( index -= old_size - new_size ))
+ (( ++i ))
+ (( i <= cword ))
+ [[ 46 -ge 19 ]]
+ [[ 'ln -s /dev/n %q\n != \'\l\n\ \-\s\ \/\d\e\v\/\n\ \%\q\\\n\' ]]
+ cur=''\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( index > 0 ))
+ (( index-- ))
+ [[ 45 -ge 19 ]]
+ [[ 'ln -s /dev/n %q\n' != \'\l\n\ \-\s\ \/\d\e\v\/\n\ \%\q\\\n\' ]]
+ (( i < cword ))
+ (( ++i ))
+ (( i <= cword ))
+ [[ -n 'ln -s /dev/n %q\n' "${FILENAME}" ; done | sh ]]
+ [[ ! -n 'ln-s/dev/n%q\n'"${FILENAME}";done|sh ]]
+ (( index < 0 ))
+ local words cword cur
+ _upvars -a7 words printf ''\''ln -s /dev/n %q\n'\''' '"${FILENAME}"' ';' done '|' sh -v cword 1 -v cur ''\''ln -s /dev/n'
+ (( 15 ))
+ (( 15 ))
+ case $1 in
+ [[ -n 7 ]]
+ printf %d 7
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:7}")'
words=("${@:3:7}")
++ words=("${@:3:7}")
+ shift 9
+ (( 6 ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
cword="$3"
++ cword=1
+ shift 3
+ (( 3 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
cur="$3"
++ cur=''\''ln -s /dev/n'
+ shift 3
+ (( 0 ))
+ [[ -v vcur ]]
+ upvars+=("$vcur")
+ upargs+=(-v $vcur "$cur")
+ [[ -v vcword ]]
+ [[ -v vprev ]]
+ [[ -v vwords ]]
+ (( 1 ))
+ local cur
+ _upvars -v cur ''\''ln -s /dev/n'
+ (( 3 ))
+ (( 3 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
cur="$3"
++ cur=''\''ln -s /dev/n'
+ shift 3
+ (( 0 ))
+ (( COMP_CWORD == 0 ))
+ local cmd=printf compcmd=printf
++ complete -p printf
+ local 'cspec=complete -F _minimal printf'
+ [[ ! -n complete -F _minimal printf ]]
+ [[ ! -n complete -F _minimal printf ]]
+ [[ -n complete -F _minimal printf ]]
+ [[ _minimal printf != \c\o\m\p\l\e\t\e\ \-\F\ \_\m\i\n\i\m\a\l\ \p\r\i\n\t\f ]]
+ local 'func=_minimal printf'
+ func=_minimal
+ (( 7 >= 2 ))
+ _minimal printf sh '|'
+ local cur prev words cword split
+ _init_completion -s
+ local exclude= flag outx errx inx OPTIND=1
+ getopts n:e:o:i:s flag -s
+ case $flag in
+ split=false
+ exclude+==
+ getopts n:e:o:i:s flag -s
+ COMPREPLY=()
+ local 'redir=@(?([0-9])<|?([0-9&])>?(>)|>&)'
+ _get_comp_words_by_ref -n '=<>&' cur prev words cword
+ 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 words cword
+ case $flag in
+ exclude='=<>&'
+ getopts c:i:n:p:w: flag -n '=<>&' cur prev words cword
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} in
+ vcur=cur
+ (( OPTIND += 1 ))
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ (( OPTIND += 1 ))
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ (( OPTIND += 1 ))
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ (( OPTIND += 1 ))
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref '=<>&' words cword cur
+ words=()
+ local cword words
+ __reassemble_comp_words_by_ref '=<>&' words cword
+ local exclude i j line ref
+ [[ -n =<>& ]]
+ exclude='[=<>&]'
+ printf -v cword %s 1
+ [[ -v exclude ]]
+ line=' printf '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( i = 0, j = 0 ))
+ (( i < 7 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ printf -v 'words[0]' %s printf
+ line=' '\''ln -s /dev/n %q\n'\'' "${FILENAME}" ; done | sh'
+ (( i == COMP_CWORD ))
+ (( i++, j++ ))
+ (( i < 7 ))
+ [[ 1 -gt 0 ]]
+ [[ 'ln -s /dev/n %q\n' == +([=<>&]) ]]
+ ref='words[1]'
+ printf -v 'words[1]' %s ''\''ln -s /dev/n %q\n'\'''
+ line=' "${FILENAME}" ; done | sh'
+ (( i == COMP_CWORD ))
+ printf -v cword %s 1
+ (( i++, j++ ))
+ (( i < 7 ))
+ [[ 2 -gt 0 ]]
bash: COMP_WORDS[i]: unbound variable
Thanks, Chris.
Yup, reproduced, thanks.
I think I might have found another case:
scp someKnownHostname:fo<TAB>
bash: $1: unbound variable
also fails for me, when I try to complete
the remote pathnames.
I can't seem to be able to reproduce that one. Please file a new issue about that and complete the info requested in it so we can debug that one further.
Describe the bug
There are some new occasions of unbound variables, which AFAIU, #44 are now considered bugs.
To reproduce
Invoke "set -u" before invoking bash-completion in .bashrc. Launching a new shell, gives:
Versions (please complete the following information)
echo "$BASH_VERSION"
: 5.1.8(1)-release(IFS=.; echo "${BASH_COMPLETION_VERSINFO[*]}")
: 2.11