web-dev-qa-db-fra.com

Est-il possible d'obtenir la complétion de tabulation avec sftp?

Parfois, je dois copier rapidement un fichier de mon serveur distant sur mon ordinateur local. Voici mon flux de travail actuel:

  1. Je SSH dans mon serveur distant, trouve le fichier et copie son chemin complet.
  2. J'ouvre un nouvel onglet de terminal et tape:

sftp user@hostname:/path/to/file (où/path/to/file est le chemin que j'ai précédemment copié)

Ce n'est pas si pénible, mais ce serait vraiment bien si je pouvais sauter l'étape 1 et trouver le chemin du fichier en utilisant la complétion de tabulation directement lors de la frappe de la commande sftp.

Pour illustrer cela, je pourrais commencer à taper sftp user@hostname:/ appuyer sur TAB et obtenir une liste des dossiers dans /. Je pourrais ensuite continuer à taper ho appuyer sur TAB et il serait auto-complet pour home, etc. etc.

Je ne suis pas sûr qu'une telle fonctionnalité existe et sinon, est-il théoriquement possible d'écrire un script de complétion d'onglet personnalisé comme décrit? Des indications sur par où commencer?

15
Olivier Lalonde

Grâce à la réponse de shellholic, j'ai pu le faire (un peu) bien pour sftp. Commencez par créer le fichier /etc/bash_completion.d/sftp avec le contenu suivant:

# 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

Ensuite, en bash, vous devez exécuter . /etc/bash_completion.d/sftp afin de charger le script.

Tout ce que j'ai vraiment fait est de copier/coller le script d'achèvement de scp de /etc/bash_completion.d/ssh et de remplacer les occurrences de scp par sftp.

7
Olivier Lalonde

Une autre alternative: utilisez lftp à la place, qui a une superbe finition par onglets intégrés (mais ce sera une fois que vous le démarrerez, pas dans le shell.) Il peut parler de sftp et de nombreux autres protocoles.

4
poolie

N'utilisez pas sftp, utilisez scp et ça marche. Vous aurez besoin d'une clé ssh.

2
shellholic

J'ai entendu dire qu'un programme appelé avec readline autorisera le programme standard en ligne de commande OpenSSH sftp pour utiliser la complétion par tabulation. Je ne peux pas vérifier que cela fonctionne, mais cela fait des années que je veux cette même fonctionnalité.

informations sur with-readline et sftp: http://www.greenend.org.uk/rjk/2005/withreadline.html

lien avec readline: http://www.greenend.org.uk/rjk/2005/with-readline-0.1.tar.bz2

Faites moi savoir comment ça marche pour vous.

1
Harvey