Bug 1477639 - Bash completion does not work within backtick.
Bash completion does not work within backtick.
Status: ASSIGNED
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: bash-completion (Show other bugs)
7.4
Unspecified Unspecified
medium Severity medium
: rc
: ---
Assigned To: Siteshwar Vashisht
:
Depends On:
Blocks: 1482562
  Show dependency treegraph
 
Reported: 2017-08-02 10:09 EDT by Ryan Blakley
Modified: 2017-08-17 11:01 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1482562 (view as bug list)
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Ryan Blakley 2017-08-02 10:09:55 EDT
Description of problem: If the bash-completion package is installed on the server, then tab completion within backticks no longer work.

Version-Release number of selected component (if applicable): Tested and reproduced on the latest 7.4 GA, and on F26.

Steps to Reproduce:
# cd /tmp
# touch file{1..5}
# for i in `cat file[tab][tab] <<--Does not complete.

Actual results: Nothing happens.

Expected results: 
** Display the available files within the directory, example below with the bash-completion package removed.
root@ryan-rhel7 /tmp # for i in `cat file
file1  file2  file3  file4  file5  
root@ryan-rhel7 /tmp # for i in `cat file

Additional info:

** Figured out what is causing the issue, the below snippet from /usr/share/bash-completion/bash_completion
  50 # Turn on extended globbing and programmable completion
  51 shopt -s extglob progcomp

** Setting extglob appears to cause the tab completion not to work, if I remove extglob then tab completion works as expected. But when sshing into the server or logging in on the console, syntax errors are displayed due to the file being sourced on login. I wasn't able to find a way to set extglob when it was needed, and then unset when not in the bash_completion file.

** Below is the output of [tab][tab] with set -x, we can see that it stops splitting the words once it encounters the backtick.

root@ryan-rhel7 /tmp # for i in `cat file+ local compfile=./completions
+ [[ /usr/share/bash-completion/bash_completion == */* ]]
+ compfile=/usr/share/bash-completion/completions
+ compfile+=/for
+ [[ -f /usr/share/bash-completion/completions/for ]]
+ complete -F _minimal for
+ return 124
+ 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
+ let 'OPTIND += 1'
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} in
+ vprev=prev
+ let 'OPTIND += 1'
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} in
+ vwords=words
+ let 'OPTIND += 1'
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} in
+ vcword=cword
+ let '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='=<>&'
+ eval cword=3
++ cword=3
+ [[ -n =<>& ]]
+ line='for i in `cat file'
+ (( i=0, j=0 ))
+ (( i < 4 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ eval 'words[0]=${!ref}${COMP_WORDS[i]}'
++ words[0]=for
+ line=' i in `cat file'
+ [[ 0 == 3 ]]
+ (( i++, j++ ))
+ (( i < 4 ))
+ [[ 1 -gt 0 ]]
+ [[ i == +([=<>&]) ]]
+ ref='words[1]'
+ eval 'words[1]=${!ref}${COMP_WORDS[i]}'
++ words[1]=i
+ line=' in `cat file'
+ [[ 1 == 3 ]]
+ (( i++, j++ ))
+ (( i < 4 ))
+ [[ 2 -gt 0 ]]
+ [[ in == +([=<>&]) ]]
+ ref='words[2]'
+ eval 'words[2]=${!ref}${COMP_WORDS[i]}'
++ words[2]=in
+ line=' `cat file'
+ [[ 2 == 3 ]]
+ (( i++, j++ ))
+ (( i < 4 ))
+ [[ 3 -gt 0 ]]
+ [[ `cat file == +([=<>&]) ]]
+ ref='words[3]'
+ eval 'words[3]=${!ref}${COMP_WORDS[i]}'
++ words[3]='`cat file' <<<---So the problem starts here, it stops splitting the words after the back tick, not sure if this is by design or now.
+ line=
+ [[ 3 == 3 ]]
+ eval cword=3
++ cword=3
+ (( i++, j++ ))
+ (( i < 4 ))
+ [[ 4 == 3 ]]
+ local i cur index=18 'lead=for i in `cat file'
+ [[ 18 -gt 0 ]]
+ [[ -n for i in `cat file ]]
+ [[ -n foriin`catfile ]]
+ cur='for i in `cat file'
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 18 -ge 3 ]]
+ [[ for != \f\o\r ]]
+ [[ 0 -lt 3 ]]
+ local old_size=18
+ cur=' i in `cat file'
+ local new_size=15
+ index=15
+ (( ++i  ))
+ (( i <= cword ))
+ [[ 15 -ge 1 ]]
+ [[   != \i ]]
+ cur='i in `cat file'
+ (( index-- ))
+ [[ 14 -ge 1 ]]
+ [[ i != \i ]]
+ [[ 1 -lt 3 ]]
+ local old_size=14
+ cur=' in `cat file'
+ local new_size=13
+ index=13
+ (( ++i  ))
+ (( i <= cword ))
+ [[ 13 -ge 2 ]]
+ [[  i != \i\n ]]
+ cur='in `cat file'
+ (( index-- ))
+ [[ 12 -ge 2 ]]
+ [[ in != \i\n ]]
+ [[ 2 -lt 3 ]]
+ local old_size=12
+ cur=' `cat file'
+ local new_size=10
+ index=10
+ (( ++i  ))
+ (( i <= cword ))
+ [[ 10 -ge 9 ]]
+ [[  `cat fil != \`\c\a\t\ \f\i\l\e ]]
+ cur='`cat file'
+ (( index-- ))
+ [[ 9 -ge 9 ]]
+ [[ `cat file != \`\c\a\t\ \f\i\l\e ]]
+ [[ 3 -lt 3 ]]
+ (( ++i  ))
+ (( i <= cword ))
+ [[ -n `cat file ]]
+ [[ ! -n `catfile ]]
+ [[ 9 -lt 0 ]]
+ local words cword cur
+ _upvars -a4 words for i in '`cat file' -v cword 3 -v cur '`cat file'
+ ((  12  ))
+ ((  12  ))
+ case $1 in
+ [[ -n 4 ]]
+ printf %d 4
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:4}")'
++ words=("${@:3:4}")
+ shift 6
+ ((  6  ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=3
+ shift 3
+ ((  3  ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur='`cat file'
+ shift 3
+ ((  0  ))
+ [[ -n cur ]]
+ upvars+=("$vcur")
+ upargs+=(-v $vcur "$cur")
+ [[ -n cword ]]
+ upvars+=("$vcword")
+ upargs+=(-v $vcword "$cword")
+ [[ -n prev ]]
+ [[ 3 -ge 1 ]]
+ upvars+=("$vprev")
+ upargs+=(-v $vprev "${words[cword - 1]}")
+ [[ -n words ]]
+ upvars+=("$vwords")
+ upargs+=(-a${#words[@]} $vwords "${words[@]}")
+ ((  4  ))
+ local cur cword prev words
+ _upvars -v cur '`cat file' -v cword 3 -v prev in -a4 words for i in '`cat file'
+ ((  15  ))
+ ((  15  ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur='`cat file'
+ shift 3
+ ((  12  ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=3
+ shift 3
+ ((  9  ))
+ case $1 in
+ [[ -n prev ]]
+ unset -v prev
+ eval 'prev="$3"'
++ prev=in
+ shift 3
+ ((  6  ))
+ case $1 in
+ [[ -n 4 ]]
+ printf %d 4
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:4}")'
++ words=("${@:3:4}")
+ shift 6
+ ((  0  ))
+ _variables
+ [[ `cat file =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]
+ return 1
+ [[ `cat file == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ [[ in == @(?([0-9])<|?([0-9&])>?(>)|>&) ]]
+ local i skip
+ (( i=1 ))
+ (( i < 4 ))
+ [[ i == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ i=2
+ (( 1 ))
+ (( i < 4 ))
+ [[ in == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ i=3
+ (( 1 ))
+ (( i < 4 ))
+ [[ `cat file == @(?([0-9])<|?([0-9&])>?(>)|>&)* ]]
+ i=4
+ (( 1 ))
+ (( i < 4 ))
+ [[ 3 -eq 0 ]]
+ prev=in
+ [[ -n false ]]
+ _split_longopt
+ [[ `cat file == --?*=* ]]
+ return 1
+ return 0
+ false
+ _filedir
+ local i 'IFS=
' xspec
+ _tilde '`cat file'
+ local result=0
+ [[ `cat file == \~* ]]
+ return 0
+ local -a toks
+ local quoted x tmp
+ _quote_readline_by_ref '`cat file' quoted
+ [[ `cat file == \'* ]]
+ printf -v quoted %q '`cat file'
+ [[ \`cat\ file == \$* ]]
++ compgen -d -- '\`cat\ file'
+ x=
+ [[ '' != -d ]]
+ xspec=
++ compgen -f -X '' -- '\`cat\ file'
+ x=
+ [[ -n '' ]]
+ [[ 0 -ne 0 ]]
Comment 2 Siteshwar Vashisht 2017-08-04 08:50:41 EDT
https://github.com/scop/bash-completion/issues/151
Comment 3 Siteshwar Vashisht 2017-08-04 09:54:02 EDT
It works when 'extglob' is not enabled in bash_completion file because sourcing of bash_completion is not completed due to errors. So default completions are used.

Note You need to log in before you can comment on or make changes to this bug.