scop / bash-completion

Programmable completion functions for bash
GNU General Public License v2.0
2.9k stars 380 forks source link

scp remote path completion no longer working since 2.12 #1157

Closed upekkha closed 5 months ago

upekkha commented 6 months ago

Describe the bug

The completion of remote paths with scp is no longer working for me since 2.12.

To reproduce

scp example.com:/et<tab>

Expected behavior

Should complete the remote path to /etc (for instance)

Versions (please complete the following information)

Additional context

First hit by the bug on macOS with homebrew, it seems to be also reproducible in Debian 12 with the current 2.13 tarball.

Starting from a bash without config files and env vars, I source the bash completion, and try completing an scp command.

env -i $(which bash) --norc --noprofile
. bash_completion
set -x
scp example.com:/et<tab>

Debug trace

Showing the last lines with inline comments added.

[...]
+ _comp_xfunc_scp_compgen_remote_files     # <----- calling the new function from 2.12
+ cur=example.com:/et
+ local _userhost=example.com
+ local _path=/et
++ command sed -e 's/\\\\\\\([][(){}<>"'\'',:;^&!$=?`\\|[:space:]]\)/\\\1/g'
+ _path=/et
+ [[ ! -n /et ]]
+ local _files
+ [[ '' == -d ]]
++ ssh -o 'Batchmode yes' example.com command ls -aF1dL '/et*'
++ command sed -e 's/[][(){}<>"'\'',:;^&!$=?`\\|[:space:]]/\\\\\\&/g' -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g'
+ _files=/etc/                      # <----- ssh command was working and returned the correct /etc
+ _comp_compgen_split -l -- /etc/
+ local '_ifs=
'
+ _compgen_options=()
+ local -a _compgen_options
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :lF:X:S:P:o: _opt -l -- /etc/
+ case $_opt in
+ _ifs='
'
+ getopts :lF:X:S:P:o: _opt -l -- /etc/
+ shift 2
+ (( 1 != 1 ))
+ local input=/etc/ 'IFS=
'
+ _comp_compgen -F '
' -U input -- -W '$input'
+ local _append=
+ local _var=
+ local _cur=example.com:/et
+ local _dir=
+ local '_ifs=
' _has_ifs=
+ local _icmd= _xcmd=
+ _upvars=()
+ local -a _upvars
+ local _old_nocasematch=
+ shopt -q nocasematch
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :av:U:Rc:C:lF:i:x: _opt -F '
' -U input -- -W '$input'
+ case $_opt in
+ _has_ifs=set
+ _ifs='
'
+ getopts :av:U:Rc:C:lF:i:x: _opt -F '
' -U input -- -W '$input'
+ case $_opt in
+ [[ input == @(*[^_a-zA-Z0-9]*|[0-9]*|) ]]
+ [[ input == @(_*|IFS|OPTIND|OPTARG|OPTERR|cur) ]]
+ _upvars+=("$OPTARG")
+ getopts :av:U:Rc:C:lF:i:x: _opt -F '
' -U input -- -W '$input'
+ [[ -n '' ]]
+ shift 5
+ (( 2 == 0 ))
+ [[ ! -n '' ]]
+ _var=COMPREPLY
+ [[ -n '' ]]
+ _append=
+ [[ -W != -* ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
+ local 'IFS=
'
+ [[ -W $input == *\$[0-9]* ]]
+ [[ -W $input == *\$\{[0-9]* ]]
+ local _result
++ [[ -n '' ]]
++ IFS='
'
++ compgen -W '$input' -- example.com:/et
+ _result=
+ _comp_compgen__error_fallback
+ local _status=1
+ [[ -n '' ]]
+ eval -- 'COMPREPLY=()'
++ COMPREPLY=()
+ return 1
+ return
+ return
# <---- but no completion to /etc is performed

As comparison, the last lines of 2.11, where the completion is working:

+ _scp_remote_files    # <----- calling the old function
+ local 'IFS=
'
+ cur=example.com:/et
+ local userhost=example.com
+ local path=/et
++ command sed -e 's/\\\\\\\([][(){}<>"'\'',:;^&!$=?`\\|[:space:]]\)/\\\1/g'
+ path=/et
+ [[ -z /et ]]
+ local files
+ [[ '' == -d ]]
++ ssh -o 'Batchmode yes' example.com command ls -aF1dL '/et*'
++ command sed -e 's/[][(){}<>"'\'',:;^&!$=?`\\|[:space:]]/\\\\\\&/g' -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g'
+ files=/etc/        # <----- ssh command was working and returned the correct /etc
+ COMPREPLY+=($files)
+ return
c/           # <------ correct completion to from /et to /etc/
akinomyoga commented 6 months ago

Thank you for the detailed report.

z1atk0 commented 6 months ago

The rsync completion had the same problem in 2.12, ie. it wouldn't complete the remote path on doing something like rsync -avP remote-host:/et<TAB> ... haven't tried 2.13.0 yet. Sorry for coming up late with this! :innocent:

akinomyoga commented 6 months ago

Thanks for the additional information. The rsync completion actually uses the same function _comp_xfunc_scp_compgen_remote_files. I confirmed the behavior of rsync in 2.13 and also confirmed that it is fixed by #1158.

upekkha commented 6 months ago

Thanks for the quick fix. Works like a charm for scp and rsync.