Skip to content

rsync will not fully complete paths with spaces. #1727

Description

@Roy-Orbison

Describe the bug

When the current completion is a file/dir, rsync will tab-complete up to and including an item with a space in its name but not below.

To reproduce

  1. Make test dirs:
    mkdir -p foo\ qux/ba{r,z}
  2. Complete from input like this:
    rsync foo
    or
    rsync 'foo
    It should get to this output:
    rsync foo\ qux/
    which works, or
    rsync 'foo qux'/
    which doesn't.
  3. Continue completion for subdirectories (at least for the unquoted version).
  4. Nothing further is output.

Replacing rsync with ls in the above examples will complete all as expected. I know they are not equivalent as rsync has to be more intelligent to do host names and remote items.

Expected behavior

It should complete items below the directory with spaces, e.g.:

rsync foo\ qux/ba
bar/ baz/

Versions (please complete the following information)

  • Operating system name/distribution and version: Debian 13 & Ubuntu 26.04
  • bash version, echo "$BASH_VERSION": 5.2.37(1)-release & 5.3.9(1)-release
  • bash-completion version, (IFS=.; echo "${BASH_COMPLETION_VERSINFO[*]}"): 2.16.0

Additional context

I also tried with the latest version of the rsync.bash file from GitHub, same problem. I see no compgen -f in the trace.

Debug trace

+ local cur prev words cword was_split comp_args
+ _comp_initialize -s -n : -- rsync 'foo\ qux/' rsync
+ local exclude= opt_split= outx= errx= inx=
+ local flag OPTIND=1 OPTARG= OPTERR=0
+ getopts n:e:o:i:s flag -s -n : -- rsync 'foo\ qux/' rsync
+ case $flag in
+ opt_split=set
+ was_split=
+ exclude+==
+ getopts n:e:o:i:s flag -s -n : -- rsync 'foo\ qux/' rsync
+ case $flag in
+ exclude+=:
+ getopts n:e:o:i:s flag -s -n : -- rsync 'foo\ qux/' rsync
+ shift 4
+ (( 3 ))
+ comp_args=("$@")
+ COMPREPLY=()
+ local 'redir=@(?(+([0-9])|{[a-zA-Z_]*([a-zA-Z_0-9])})@(>?([>|&])|<?([>&])|<<?([-<]))|&>?(>))'
+ _comp_get_words -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 ]]
+ _comp__get_cword_at_cursor '=:<>&' words cword cur
+ words=()
+ local cword words
+ _comp__reassemble_words '=:<>&' words cword
+ local exclude= i j line ref
+ [[ -n =:<>& ]]
+ exclude='[=:<>&]'
+ printf -v cword %s 1
+ [[ -n [=:<>&] ]]
+ line='rsync foo\ qux/'
+ (( i = 0, j = 0 ))
+ (( i < 2 ))
+ [[ 0 -gt 0 ]]
+ ref='words[0]'
+ printf -v 'words[0]' %s rsync
+ line=' foo\ qux/'
+ (( i == COMP_CWORD ))
+ (( i++, j++ ))
+ (( i < 2 ))
+ [[ 1 -gt 0 ]]
+ [[ foo\ qux/ == +([=:<>&]) ]]
+ ref='words[1]'
+ printf -v 'words[1]' %s 'foo\ qux/'
+ line=
+ (( i == COMP_CWORD ))
+ printf -v cword %s 1
+ (( i++, j++ ))
+ (( i < 2 ))
+ (( i == COMP_CWORD ))
+ local i cur= index=15 'lead=rsync foo\ qux/'
+ [[ 15 -gt 0 ]]
+ [[ -n rsync foo\ qux/ ]]
+ [[ -n rsyncfoo\qux/ ]]
+ cur='rsync foo\ qux/'
+ (( i = 0 ))
+ (( i <= cword ))
+ [[ 15 -ge 5 ]]
+ [[ rsync != \r\s\y\n\c ]]
+ (( i < cword ))
+ local old_size=15
+ cur=' foo\ qux/'
+ local new_size=10
+ (( index -= old_size - new_size ))
+ (( ++i ))
+ (( i <= cword ))
+ [[ 10 -ge 9 ]]
+ [[  foo\ qux != \f\o\o\\\ \q\u\x\/ ]]
+ cur='foo\ qux/'
+ (( index > 0 ))
+ (( index-- ))
+ [[ 9 -ge 9 ]]
+ [[ foo\ qux/ != \f\o\o\\\ \q\u\x\/ ]]
+ (( i < cword ))
+ (( ++i ))
+ (( i <= cword ))
+ [[ -n foo\ qux/ ]]
+ [[ ! -n foo\qux/ ]]
+ (( index < 0 ))
+ local 'IFS=
'
+ local words cword cur
+ _comp_upvars -a2 words rsync 'foo\ qux/' -v cword 1 -v cur 'foo\ qux/'
+ (( 10 ))
+ (( 10 ))
+ case $1 in
+ [[ -n 2 ]]
+ printf %d 2
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:2}")'
++ words=("${@:3:2}")
+ shift 4
+ (( 6 ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=1
+ shift 3
+ (( 3 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur='foo\ qux/'
+ shift 3
+ (( 0 ))
+ [[ -n cur ]]
+ upvars+=("$vcur")
+ upargs+=(-v "$vcur" "$cur")
+ [[ -n cword ]]
+ upvars+=("$vcword")
+ upargs+=(-v "$vcword" "$cword")
+ [[ -n prev ]]
+ local value=
+ (( cword >= 1 ))
+ value=rsync
+ upvars+=("$vprev")
+ upargs+=(-v "$vprev" "$value")
+ [[ -n words ]]
+ local 'IFS=
'
+ upvars+=("$vwords")
+ upargs+=(-a"${#words[@]}" "$vwords" ${words+"${words[@]}"})
+ (( 4 ))
+ local cur cword prev words
+ _comp_upvars -v cur 'foo\ qux/' -v cword 1 -v prev rsync -a2 words rsync 'foo\ qux/'
+ (( 13 ))
+ (( 13 ))
+ case $1 in
+ [[ -n cur ]]
+ unset -v cur
+ eval 'cur="$3"'
++ cur='foo\ qux/'
+ shift 3
+ (( 10 ))
+ case $1 in
+ [[ -n cword ]]
+ unset -v cword
+ eval 'cword="$3"'
++ cword=1
+ shift 3
+ (( 7 ))
+ case $1 in
+ [[ -n prev ]]
+ unset -v prev
+ eval 'prev="$3"'
++ prev=rsync
+ shift 3
+ (( 4 ))
+ case $1 in
+ [[ -n 2 ]]
+ printf %d 2
+ [[ -n words ]]
+ unset -v words
+ eval 'words=("${@:3:2}")'
++ words=("${@:3:2}")
+ shift 4
+ (( 0 ))
+ _comp_compgen_variables
+ [[ foo\ qux/ =~ ^(\$(\{[!#]?)?)([A-Za-z0-9_]*)$ ]]
+ [[ foo\ qux/ =~ ^(\$\{[#!]?)([A-Za-z0-9_]*)\[([^]]*)$ ]]
+ [[ foo\ qux/ =~ ^\$\{[#!]?[A-Za-z0-9_]*\[.*]$ ]]
+ return 1
+ [[ foo\ qux/ == @(?(+([0-9])|{[a-zA-Z_]*([a-zA-Z_0-9])})@(>?([>|&])|<?([>&])|<<?([-<]))|&>?(>))* ]]
+ [[ rsync == @(?(+([0-9])|{[a-zA-Z_]*([a-zA-Z_0-9])})@(>?([>|&])|<?([>&])|<<?([-<]))|&>?(>)) ]]
+ local i skip
+ (( i = 1 ))
+ (( i < 2 ))
+ [[ foo\ qux/ == @(?(+([0-9])|{[a-zA-Z_]*([a-zA-Z_0-9])})@(>?([>|&])|<?([>&])|<<?([-<]))|&>?(>))* ]]
+ (( i++ ))
+ (( 1 ))
+ (( i < 2 ))
+ (( cword <= 0 ))
+ prev=rsync
+ [[ -n set ]]
+ _comp__split_longopt
+ [[ foo\ qux/ == --?*=* ]]
+ return 1
+ return 0
+ local 'noargopts=!(-*|*[Te]*)'
+ case $prev in
+ [[ -n '' ]]
+ _comp_expand
+ case ${cur-} in
+ return 0
+ case $cur in
+ _comp_compgen_known_hosts -c -a -- 'foo\ qux/'
+ local known_hosts
+ _comp_compgen_known_hosts__impl -c -a -- 'foo\ qux/'
+ known_hosts=()
+ local configfile= flag prefix=
+ local cur suffix= aliases= i host ipv4= ipv6=
+ tmpkh=()
+ khd=()
+ config=()
+ local -a kh tmpkh khd config
+ local OPTIND=1
+ getopts ac46F:p: flag -c -a -- 'foo\ qux/'
+ case $flag in
+ suffix=:
+ getopts ac46F:p: flag -c -a -- 'foo\ qux/'
+ case $flag in
+ aliases=set
+ getopts ac46F:p: flag -c -a -- 'foo\ qux/'
+ (( 4 < OPTIND ))
+ cur='foo\ qux/'
+ (( OPTIND += 1 ))
+ (( 4 >= OPTIND ))
+ [[ foo\ qux/ == *@* ]]
+ kh=()
+ [[ -n '' ]]
+ for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config
+ [[ -r /etc/ssh/ssh_config ]]
+ [[ ! -d /etc/ssh/ssh_config ]]
+ config+=("$i")
+ for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config
+ [[ -r /home/roy/.ssh/config ]]
+ for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config
+ [[ -r /home/roy/.ssh2/config ]]
+ (( 1 > 0 ))
+ for i in "${config[@]}"
+ _comp__included_ssh_config_files /etc/ssh/ssh_config
+ (( 1 < 1 ))
+ local configfile i files f REPLY
+ configfile=/etc/ssh/ssh_config
+ local relative_include_base
+ [[ /etc/ssh/ssh_config == /etc/ssh* ]]
+ relative_include_base=/etc/ssh
+ local depth=1
+ local -a included
+ local -a include_files
+ included=("$configfile")
+ local max_depth=16
+ (( 1 > 0 && depth++ < max_depth ))
++ command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\(.*\)$/\1/p' /etc/ssh/ssh_config
+ _comp_split include_files '/etc/ssh/ssh_config.d/*.conf'
+ local _append= 'IFS=
'
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :alF: _opt include_files '/etc/ssh/ssh_config.d/*.conf'
+ shift 0
+ (( 2 != 2 ))
+ [[ include_files == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace
+ set -o noglob
+ local _old_size _new_size
+ [[ -n '' ]]
+ _old_size=0
+ eval 'include_files=($2)'
++ include_files=($2)
+ eval '_new_size=${#include_files[@]}'
++ _new_size=1
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace: == *:noglob:* ]]
+ set +o noglob
+ (( _new_size > _old_size ))
+ included=()
+ for i in "${include_files[@]}"
+ [[ /etc/ssh/ssh_config.d/*.conf != [~/]* ]]
+ _comp_expand_tilde '/etc/ssh/ssh_config.d/*.conf'
+ REPLY='/etc/ssh/ssh_config.d/*.conf'
+ [[ /etc/ssh/ssh_config.d/*.conf == \~* ]]
+ _comp_expand_glob files '$REPLY'
+ (( 2 != 2 ))
+ [[ files == @(GLOBIGNORE|GLOBSORT|_*|*[^_a-zA-Z0-9]*|[0-9]*|) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath
+ set +o noglob
+ shopt -s nullglob
+ shopt -u failglob dotglob
+ local GLOBIGNORE= GLOBSORT=name
+ local LC_COLLATE=C LC_CTYPE=en_AU.UTF-8 LC_ALL=
+ eval -- 'files=()'
++ files=()
+ eval -- 'files=($REPLY)'
++ files=($REPLY)
+ _comp_unlocal GLOBIGNORE
+ (( BASH_VERSINFO[0] >= 5 ))
+ shopt -q localvar_unset
+ unset -v GLOBIGNORE
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:dotglob:* ]]
+ shopt -u dotglob
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:nullglob:* ]]
+ shopt -u nullglob
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:failglob:* ]]
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:noglob:* ]]
+ eval '((${#files[@]}))'
++ (( 1 ))
+ for f in "${files[@]}"
+ [[ -r /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf ]]
+ [[ ! -d /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf ]]
+ config+=("$f")
+ included+=("$f")
+ (( 1 > 0 && depth++ < max_depth ))
++ command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\(.*\)$/\1/p' /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
+ _comp_split include_files ''
+ local _append= 'IFS=
'
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :alF: _opt include_files ''
+ shift 0
+ (( 2 != 2 ))
+ [[ include_files == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace
+ set -o noglob
+ local _old_size _new_size
+ [[ -n '' ]]
+ _old_size=0
+ eval 'include_files=($2)'
++ include_files=($2)
+ eval '_new_size=${#include_files[@]}'
++ _new_size=0
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace: == *:noglob:* ]]
+ set +o noglob
+ (( _new_size > _old_size ))
+ return
+ (( 2 > 0 ))
++ _comp_awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t=]+", "") { print $0 }' /etc/ssh/ssh_config /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
++ sort -u
++ command awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t=]+", "") { print $0 }' /etc/ssh/ssh_config /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
+ _comp_split -l tmpkh /dev/null
+ local _append= 'IFS=
'
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :alF: _opt -l tmpkh /dev/null
+ case $_opt in
+ IFS='
'
+ getopts :alF: _opt -l tmpkh /dev/null
+ shift 1
+ (( 2 != 2 ))
+ [[ tmpkh == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace
+ set -o noglob
+ local _old_size _new_size
+ [[ -n '' ]]
+ _old_size=0
+ eval 'tmpkh=($2)'
++ tmpkh=($2)
+ eval '_new_size=${#tmpkh[@]}'
++ _new_size=1
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace: == *:noglob:* ]]
+ set +o noglob
+ (( _new_size > _old_size ))
+ local tmpkh2 j REPLY
+ for i in "${tmpkh[@]}"
+ [[ /dev/null =~ ^([^"]*)"([^"]*)"(.*)$ ]]
+ _comp_split tmpkh2 /dev/null
+ local _append= 'IFS=
'
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :alF: _opt tmpkh2 /dev/null
+ shift 0
+ (( 2 != 2 ))
+ [[ tmpkh2 == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace
+ set -o noglob
+ local _old_size _new_size
+ [[ -n '' ]]
+ _old_size=0
+ eval 'tmpkh2=($2)'
++ tmpkh2=($2)
+ eval '_new_size=${#tmpkh2[@]}'
++ _new_size=1
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace: == *:noglob:* ]]
+ set +o noglob
+ (( _new_size > _old_size ))
+ for j in "${tmpkh2[@]}"
+ _comp_expand_tilde /dev/null
+ REPLY=/dev/null
+ [[ /dev/null == \~* ]]
+ [[ -r /dev/null ]]
+ kh+=("$REPLY")
+ [[ ! -n '' ]]
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /etc/ssh/ssh_known_hosts ]]
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /etc/ssh/ssh_known_hosts2 ]]
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /etc/known_hosts ]]
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /etc/known_hosts2 ]]
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /home/roy/.ssh/known_hosts ]]
+ [[ ! -d /home/roy/.ssh/known_hosts ]]
+ kh+=("$i")
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts ~/.ssh/known_hosts2
+ [[ -r /home/roy/.ssh/known_hosts2 ]]
+ for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys
+ [[ -d /etc/ssh2/knownhosts ]]
+ continue
+ for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys
+ [[ -d /home/roy/.ssh2/hostkeys ]]
+ continue
+ (( 2 + 0 > 0 ))
+ (( 2 > 0 ))
+ for i in "${kh[@]}"
+ read -ra tmpkh
+ for i in "${kh[@]}"
+ read -ra tmpkh
+ (( 3 == 0 ))
+ [[ |1|JrSQQ2MgToYU6prdURIEZY6HOp8=|Ggxr7IbBCjuzrZnCk7pQ9XPbSbw= == [\|\#]* ]]
+ continue
+ read -ra tmpkh
+ (( 3 == 0 ))
+ [[ |1|I9TE6DD03JZrm8/to4JCSJDpasY=|O9AlaYixzkmhlVBc1E/r6DsEQQQ= == [\|\#]* ]]
+ continue
+ read -ra tmpkh
+ (( 0 > 0 ))
+ (( 0 ))
+ [[ 2 -gt 0 ]]
+ [[ -n set ]]
+ local -a hosts
++ command sed -ne 's/^[[:blank:]]*[Hh][Oo][Ss][Tt][[:blank:]=]\{1,\}\(.*\)$/\1/p' /etc/ssh/ssh_config /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
+ _comp_split hosts '*
.host machine/.host
unix/* vsock/* machine/*'
+ local _append= 'IFS=
'
+ local OPTIND=1 OPTARG= OPTERR=0 _opt
+ getopts :alF: _opt hosts '*
.host machine/.host
unix/* vsock/* machine/*'
+ shift 0
+ (( 2 != 2 ))
+ [[ hosts == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace
+ set -o noglob
+ local _old_size _new_size
+ [[ -n '' ]]
+ _old_size=0
+ eval 'hosts=($2)'
++ hosts=($2)
+ eval '_new_size=${#hosts[@]}'
++ _new_size=6
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace: == *:noglob:* ]]
+ set +o noglob
+ (( _new_size > _old_size ))
+ _comp_compgen -av known_hosts -- -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)'
+ local _append=
+ local _var=
+ local '_cur=foo\ qux/'
+ 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 -av known_hosts -- -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)'
+ case $_opt in
+ _append=set
+ getopts :av:U:Rc:C:lF:i:x: _opt -av known_hosts -- -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)'
+ case $_opt in
+ [[ known_hosts == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR|cur) ]]
+ _var=known_hosts
+ getopts :av:U:Rc:C:lF:i:x: _opt -av known_hosts -- -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)'
+ [[ -n '' ]]
+ shift 3
+ (( 8 == 0 ))
+ [[ ! -n known_hosts ]]
+ [[ -P != -* ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
+ local 'IFS=
'
+ [[ -P  -S : -W "${hosts[@]%%[*?%]*}" -X @(\!*|) == *\$[0-9]* ]]
+ [[ -P  -S : -W "${hosts[@]%%[*?%]*}" -X @(\!*|) == *\$\{[0-9]* ]]
+ _comp_compgen__call_builtin -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)'
+ local _result
++ [[ -n '' ]]
++ IFS='
'
++ compgen -P '' -S : -W '"${hosts[@]%%[*?%]*}"' -X '@(\!*|)' -- 'foo\ qux/'
+ _result=
+ _comp_compgen__error_fallback
+ local _status=1
+ [[ -n set ]]
+ eval -- 'known_hosts+=()'
++ known_hosts+=()
+ return 1
+ return
+ [[ -n '' ]]
+ type ruptime
+ [[ -n set ]]
+ _comp_compgen -av known_hosts -- -A hostname -P '' -S :
+ local _append=
+ local _var=
+ local '_cur=foo\ qux/'
+ 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 -av known_hosts -- -A hostname -P '' -S :
+ case $_opt in
+ _append=set
+ getopts :av:U:Rc:C:lF:i:x: _opt -av known_hosts -- -A hostname -P '' -S :
+ case $_opt in
+ [[ known_hosts == @(*[^_a-zA-Z0-9]*|[0-9]*||_*|IFS|OPTIND|OPTARG|OPTERR|cur) ]]
+ _var=known_hosts
+ getopts :av:U:Rc:C:lF:i:x: _opt -av known_hosts -- -A hostname -P '' -S :
+ [[ -n '' ]]
+ shift 3
+ (( 6 == 0 ))
+ [[ ! -n known_hosts ]]
+ [[ -A != -* ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
+ local 'IFS=
'
+ [[ -A hostname -P  -S : == *\$[0-9]* ]]
+ [[ -A hostname -P  -S : == *\$\{[0-9]* ]]
+ _comp_compgen__call_builtin -A hostname -P '' -S :
+ local _result
++ [[ -n '' ]]
++ IFS='
'
++ compgen -A hostname -P '' -S : -- 'foo\ qux/'
+ _result=
+ _comp_compgen__error_fallback
+ local _status=1
+ [[ -n set ]]
+ eval -- 'known_hosts+=()'
++ known_hosts+=()
+ return 1
+ return
+ (( 0 ))
+ return 1
+ return 1
+ _comp_compgen -ax scp local_files
+ local _append=
+ local _var=
+ local '_cur=foo\ qux/'
+ 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 -ax scp local_files
+ case $_opt in
+ _append=set
+ getopts :av:U:Rc:C:lF:i:x: _opt -ax scp local_files
+ case $_opt in
+ [[ ! -n scp ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
+ _xcmd=scp
+ getopts :av:U:Rc:C:lF:i:x: _opt -ax scp local_files
+ [[ -n '' ]]
+ shift 2
+ (( 1 == 0 ))
+ [[ ! -n '' ]]
+ _var=COMPREPLY
+ [[ -n set ]]
+ [[ local_files != -* ]]
+ [[ -n '' ]]
+ local -a _generator
+ [[ -n '' ]]
+ [[ -n scp ]]
+ _generator=(_comp_xfunc "$_xcmd" "compgen_$1")
+ declare -F -- _comp_xfunc
+ shift
+ _comp_compgen__call_generator
+ (( 0 ))
+ [[ -n '' ]]
+ local _comp_compgen__append=set
+ local _comp_compgen__var=COMPREPLY
+ local '_comp_compgen__cur=foo\ qux/' 'cur=foo\ qux/'
+ _comp_xfunc scp compgen_local_files
+ local xfunc_name=compgen_local_files
+ [[ compgen_local_files == _* ]]
+ xfunc_name=_comp_xfunc_scp_compgen_local_files
+ declare -F -- _comp_xfunc_scp_compgen_local_files
+ _comp_xfunc_scp_compgen_local_files
+ local _dirsonly=
+ [[ '' == -d ]]
+ local files
+ _comp_expand_glob files '"$cur"*'
+ (( 2 != 2 ))
+ [[ files == @(GLOBIGNORE|GLOBSORT|_*|*[^_a-zA-Z0-9]*|[0-9]*|) ]]
+ local _original_opts=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath
+ set +o noglob
+ shopt -s nullglob
+ shopt -u failglob dotglob
+ local GLOBIGNORE= GLOBSORT=name
+ local LC_COLLATE=C LC_CTYPE=en_AU.UTF-8 LC_ALL=
+ eval -- 'files=()'
++ files=()
+ eval -- 'files=("$cur"*)'
++ files=("$cur"*)
+ _comp_unlocal GLOBIGNORE
+ (( BASH_VERSINFO[0] >= 5 ))
+ shopt -q localvar_unset
+ unset -v GLOBIGNORE
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:dotglob:* ]]
+ shopt -u dotglob
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:nullglob:* ]]
+ shopt -u nullglob
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:failglob:* ]]
+ [[ :braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:xtrace:checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath: == *:noglob:* ]]
+ eval '((${#files[@]}))'
++ (( 0 ))
+ return 0
+ local _status=0
+ [[ -n '' ]]
+ return 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions