¿Es posible completar la pestaña con sftp?

15

A veces necesito copiar rápidamente un archivo de mi servidor remoto a mi máquina local. Aquí está mi flujo de trabajo actual:

  1. Me SSH en mi servidor remoto, encontrar el archivo y copiar su ruta completa.
  2. Abro una nueva pestaña de terminal y escribo:

sftp user@hostname:/path/to/file (donde / ruta / a / archivo es la ruta que copié previamente)

No es tan difícil, pero sería realmente bueno si pudiera omitir el paso 1 y encontrar la ruta al archivo usando la finalización de tabulación directamente al escribir el comando sftp.

Para ilustrar, podría comenzar a escribir sftp user@hostname:/press TABy obtener una lista de carpetas en /. Entonces podría seguir escribiendo hopress TABy se autocompletaría home, etc., etc.

No estoy seguro de si existe tal característica y, de lo contrario, ¿es teóricamente posible escribir un script de finalización de pestaña personalizado como se describe? ¿Alguna sugerencia sobre por dónde empezar?

Olivier Lalonde
fuente

Respuestas:

7

Gracias a la respuesta de shellholic, pude hacer que (algo) funcione para sftp. Primero, cree el archivo /etc/bash_completion.d/sftpcon el siguiente contenido:

# 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

Luego, en bash, debe ejecutar . /etc/bash_completion.d/sftppara cargar el script.

Todo lo que realmente hice fue copiar / pegar el script de finalización scp /etc/bash_completion.d/sshy reemplazar las ocurrencias scp con sftp.

Olivier Lalonde
fuente
4

Otra alternativa: usar lftpen su lugar, que tiene una excelente finalización de pestaña incorporada (pero eso será una vez que lo inicies, no en el shell). Puede hablar sftp y muchos otros protocolos.

billar
fuente
2

No use sftp, use scpy funciona. Necesitará una clave ssh.

concha
fuente
Gracias, pude hacerlo funcionar para sftp usando el script de autocompletado de scp. Estoy tratando de usar sftp tanto como sea posible, ya que se supone que reemplaza a scp.
Olivier Lalonde
realmente no necesitas un par de llaves para scp, ¿verdad?
Nanne