Is it possible to get tab completion with sftp?
Solution 1
Thanks to shellholic's answer, I was able to make it (somewhat) work for sftp. First, create the file /etc/bash_completion.d/sftp
with the following content:
# custom sftp(1) based on scp
# see http://askubuntu.com/questions/14645/is-it-possible-to-get-tab-completion-with-sftp
#
_sftp()
{
local configfile cur userhost path prefix
COMPREPLY=()
cur=`_get_cword ":"`
_expand || return 0
if [[ "$cur" == *:* ]]; then
local IFS=$'\t\n'
# remove backslash escape from :
cur=${cur/\\:/:}
userhost=${cur%%?(\\):*}
path=${cur#*:}
# unescape spaces
path=${path//\\\\\\\\ / }
if [ -z "$path" ]; then
# default to home dir of specified user on remote host
path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
fi
# escape spaces; remove executables, aliases, pipes and sockets;
# add space at end of file names
COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \
command ls -aF1d "$path*" 2>/dev/null | \
sed -e "s/[][(){}<>\",:;^&\!$=?\`|\\ ']/\\\\\\\\\\\\&/g" \
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
return 0
fi
if [[ "$cur" = -F* ]]; then
cur=${cur#-F}
prefix=-F
else
# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
set -- "${COMP_WORDS[@]}"
while [ $# -gt 0 ]; do
if [ "${1:0:2}" = -F ]; then
if [ ${#1} -gt 2 ]; then
configfile="$(dequote "${1:2}")"
else
shift
[ "$1" ] && configfile="$(dequote "$1")"
fi
break
fi
shift
done
[[ "$cur" == */* ]] || _known_hosts_real -c -a -F "$configfile" "$cur"
fi
# This approach is used instead of _filedir to get a space appended
# after local file/dir completions, and $nospace retained for others.
local IFS=$'\t\n'
COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | sed \
-e "s/[][(){}<>\",:;^&\!$=?\`|\\ ']/\\\\&/g" \
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/$prefix/") )
return 0
}
complete -o nospace -F _sftp sftp
Then in bash you need to execute . /etc/bash_completion.d/sftp
in order to load the script.
All I really did was copy/paste the scp completion script from /etc/bash_completion.d/ssh
and replace scp occurences with sftp.
Solution 2
Another alternative: use lftp
instead, which has superb built in tab completion (but that'll be once you start it, not in the shell.) It can talk sftp and many other protocols.
Solution 3
Don't use sftp
, use scp
and it work. You will need an ssh key.
Solution 4
I hear that a program called with-readline will allow the standard OpenSSH command line program sftp to utilize tab completion. I cannot verify that it works, but I've been wanting that same functionality for years now.
info on with-readline and sftp: http://www.greenend.org.uk/rjk/2005/withreadline.html
with-readline link: http://www.greenend.org.uk/rjk/2005/with-readline-0.1.tar.bz2
Let me know how it works for you.
Related videos on Youtube
Olivier Lalonde
Updated on September 17, 2022Comments
-
Olivier Lalonde almost 2 years
Sometimes I need to quickly copy a file from my remote server to my local machine. Here's my current workflow:
- I SSH into my remote server, find the file and copy its full path.
- I open new terminal tab and type:
sftp user@hostname:/path/to/file
(where /path/to/file is the path I previously copied)It's not such a pain but it would be really nice if I could skip step 1 and find the path to the file using tab completion directly when typing the sftp command.
To illustrate, I could start typing
sftp user@hostname:/
press TAB and get a listing of folders in /. I could then go on typingho
press TAB and it would auto-complete tohome
, etc. etc.I'm not sure if such a feature exists and otherwise, is it theoretically possible to write a custom tab completion script as described? Any pointers on where to start?
-
Olivier Lalonde over 13 yearsThanks, I was actually able to make it work for sftp using scp's auto completion's script. I'm trying to use sftp as much as possible as it is supposed to supersede scp.
-
Nanne about 11 yearsyou don't really need a key pair for scp, do you?