diff --git a/completions/ssh b/completions/ssh index db30ba340f7..279c44b040a 100644 --- a/completions/ssh +++ b/completions/ssh @@ -512,15 +512,16 @@ _comp_xfunc_scp_compgen_remote_files() # shellcheck disable=SC2090 _files=$(ssh -o 'Batchmode yes' "$_userhost" \ command ls -aF1dL "$_path*" 2>/dev/null | - command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e '/[^\/]$/d') + command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e '/[^/]$/d') else # escape problematic characters; remove executables, aliases, pipes # and sockets; add space at end of file names # shellcheck disable=SC2090 _files=$(ssh -o 'Batchmode yes' "$_userhost" \ command ls -aF1dL "$_path*" 2>/dev/null | - command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e 's/[*@|=]$//g' \ - -e 's/[^\/]$/& /g') + command sed -e 's/[*@|=]$//g' \ + -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' \ + -e 's/[^/]$/& /g') fi _comp_compgen -R split -l -- "$_files" } @@ -550,13 +551,14 @@ _comp_xfunc_scp_compgen_local_files() _comp_compgen -RU files split -l -- "$( command ls -aF1dL "${files[@]}" 2>/dev/null | command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ - -e '/[^\/]$/d' -e "s/^/${1-}/" + -e '/[^/]$/d' -e "s/^/${1-}/" )" else _comp_compgen -RU files split -l -- "$( command ls -aF1dL "${files[@]}" 2>/dev/null | - command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ - -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/${1-}/" + command sed -e 's/[*@|=]$//g' \ + -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ + -e 's/[^/]$/& /g' -e "s/^/${1-}/" )" fi } diff --git a/completions/sshfs b/completions/sshfs index 4b3f38800dc..59d0eed0eeb 100644 --- a/completions/sshfs +++ b/completions/sshfs @@ -8,9 +8,10 @@ _comp_cmd_sshfs() _comp_expand || return if [[ $cur == *:* ]]; then - _comp_compgen -x scp remote_files -d - # unlike scp and rsync, sshfs works with 1 backslash instead of 3 - COMPREPLY=("${COMPREPLY[@]//\\\\\\/\\}") + if _comp_compgen -x scp remote_files -d; then + # unlike scp and rsync, sshfs works with 1 backslash instead of 3 + COMPREPLY=("${COMPREPLY[@]//\\\\\\/\\}") + fi return fi diff --git a/test/fixtures/sshfs/local_path-dir/dummy.txt b/test/fixtures/sshfs/local_path-dir/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git "a/test/fixtures/sshfs/local_path-file\\" "b/test/fixtures/sshfs/local_path-file\\" new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/t/test_scp.py b/test/t/test_scp.py index 3bfbfff69f2..97f0e008de9 100644 --- a/test/t/test_scp.py +++ b/test/t/test_scp.py @@ -3,7 +3,12 @@ import pytest -from conftest import assert_bash_exec, assert_complete, bash_env_saved +from conftest import ( + assert_bash_exec, + assert_complete, + bash_env_saved, + prepare_fixture_dir, +) LIVE_HOST = os.environ.get( "BASH_COMPLETION_TEST_LIVE_SSH_HOST", default="bash_completion" @@ -152,3 +157,22 @@ def test_xfunc_remote_files(self, bash): "shared/default/foo ", "shared/default/foo.d/", ] + + @pytest.fixture + def tmpdir_mkfifo(self, request, bash): + tmpdir, _, _ = prepare_fixture_dir(request, files=[], dirs=[]) + + try: + assert_bash_exec(bash, "mkfifo '%s/local_path_1-pipe'" % tmpdir) + except Exception: + pytest.skip( + "The present system does not allow creating a named pipe." + ) + + return tmpdir + + def test_local_path_mark_1(self, bash, tmpdir_mkfifo): + completion = assert_complete( + bash, "scp local_path_1-", cwd=tmpdir_mkfifo + ) + assert completion == "pipe" diff --git a/test/t/test_sshfs.py b/test/t/test_sshfs.py index cb4189bf5e1..5b502461e57 100644 --- a/test/t/test_sshfs.py +++ b/test/t/test_sshfs.py @@ -1,8 +1,20 @@ import pytest +from conftest import assert_bash_exec, assert_complete + @pytest.mark.bashcomp(ignore_env=r"^[+-]_comp_cmd_scp__path_esc=") class TestSshfs: @pytest.mark.complete("sshfs ./") def test_1(self, completion): assert completion + + @pytest.mark.complete("sshfs local_path", cwd="sshfs") + def test_local_path_suffix_1(self, completion): + assert completion == "-dir/" + + def test_remote_path_ending_with_backslash(self, bash): + assert_bash_exec(bash, "ssh() { echo 'hypothetical\\'; }") + completion = assert_complete(bash, "sshfs remote_host:hypo") + assert_bash_exec(bash, "unset -f ssh") + assert not completion