Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Sometimes I need to quickly copy a file from my remote server to my local machine. Here's my current workflow:

  1. I SSH into my remote server, find the file and copy its full path.
  2. 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 typing ho press TAB and it would auto-complete to home, 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?

share|improve this question

4 Answers 4

up vote 4 down vote accepted

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.

share|improve this answer

Don't use sftp, use scp and it work. You will need an ssh key.

share|improve this answer
    
Thanks, 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. –  Olivier Lalonde Nov 24 '10 at 2:42
    
you don't really need a key pair for scp, do you? –  Nanne May 27 '13 at 6:28

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.