Noms de serveur à complétion automatique pour SSH et SCP

61

J'ai quelques serveurs configurés ~/.ssh/config, tels que alphaet beta. Comment pourrais-je configurer Bash de telle sorte que les commandes ssh al<tab>et la scp file.tgz al<tab>saisie automatique des noms des serveurs configurés?

Je ne veux pas ajouter les serveurs à un autre fichier (c'est-à-dire un tableau de Bash) à chaque fois qu'un fichier est ajouté, car nous ajoutons et retirons des serveurs régulièrement et la liste est assez longue.

dotancohen
la source
2
Le paquetage bash-complétions est-il installé pour votre distribution? Je pense que cela fait partie des routines d'achèvement standard bien que je puisse le confondre avec zsh.
Caleb
Mon installation fait exactement cela.
slm
Ceci est sur Kubuntu 12.10, et j'ai bash-completioninstallé.
dotancohen

Réponses:

64

Je l'ai trouvé !!

Il semble que dans Ubuntu les entrées ~/.ssh/known_hostssoient hachées , l’achèvement de SSH ne peut donc pas les lire. Ceci est une fonctionnalité, pas un bug. Même en ajoutant HashKnownHosts noà ~/.ssh/configet /etc/ssh/ssh_configje ne pouvais pas empêcher le hashing hôte.

Cependant, les hôtes qui m'intéressent se trouvent également dans ~/.ssh/config. Voici un script pour Bash Completion qui lit les entrées de ce fichier:

_ssh() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(grep '^Host' ~/.ssh/config ~/.ssh/config.d/* 2>/dev/null | grep -v '[?*]' | cut -d ' ' -f 2-)

    COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
    return 0
}
complete -F _ssh ssh

Placez ce script /etc/bash_completion.d/sshet sourcez-le avec la commande suivante:

$ . /etc/bash_completion.d/ssh

J’ai trouvé ce guide inestimable et je n’aurais pas pu écrire ce scénario sans lui. Merci Steve Kemp d' avoir écrit ce guide formidable!

dotancohen
la source
1
Il semble que dans Centos 6, les entrées de ~ / .ssh / known_hosts annulent les entrées de ~ / .ssh / config, par exemple. Si vous avez foo.bar.baz.com dans known_hosts, alors cela correspondra à tout si vous faites "ssh foo" <onglet> - ce n'est pas souhaitable si vous avez un autre utilisateur ou d'autres paramètres que vous souhaitez appliquer à partir de la config ssh. Si vous avez une entrée dans ssh config qui ne se complète pas automatiquement, vérifiez si elle est présente dans known_hosts et supprimez-la. Il devrait maintenant fonctionner normalement en prenant les paramètres de config.
Imran-UK
@ Imran-UK: On sait qu'Ubuntu ne fait pas cette chose sensée sous prétexte de sécurité. Apparemment, l'idée est qu'une entité malveillante pourrait, en tant qu'utilisateur, éditer ~ / .ssh / config, malgré le répertoire chmod 0600. Hé, je n'étais pas celui qui a pris la décision!
dotancohen
1
J'utilise zsh & oh-my-zsh, je viens de découvrir que l'activation du plug-in "ssh" et l'insertion de "HashKnownHosts yes" dans mon ~ / .ssh / config semblent bien agir. Vous pouvez changer de shell quelle que soit la distribution afin que cela puisse être une solution.
Imran-UK
@ Imran-UK: En fait, j'ai déjà essayé le zsh et j'ai bien l'intention de le réessayer. Je vais regarder dans cela. Shukran mon ami!
dotancohen
Je sais que je suis un peu en retard pour la fête, mais RHEL 7 permettra la saisie semi-automatique des entrées /etc/hosts, d'autres distributions peuvent faire de même.
Centimane
16

Pré-emballé

Vous ne dites pas quelle distribution vous utilisez, mais sur mon système Fedora 19, j'ai installé le paquet suivant, bash-completionqui fournit cette fonctionnalité via ce fichier de règle de complétion:

/usr/share/bash-completion/completions/ssh

Voici le paquet que j'ai installé:

$ rpm -aq |grep completion
bash-completion-2.1-2.fc19.noarch

Si vous parcourez ce fichier de règles, vous verrez des strophes interrogeant le $HOME/.ssh/configfichier:

$ grep config /usr/share/bash-completion/completions/ssh
    local configfile
    local -a config
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile
        # Search COMP_WORDS for '-F configfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile prefix
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
                _known_hosts_real -c -a -F "$configfile" "$cur"

Rouler le vôtre

J'ai aussi trouvé ce Gist, known_hosts_autocomplete.sh , qui fait quelque chose de similaire sauf avec le $HOME/.ssh/known_hostsfichier.

# add to ~/.bash_profile, and close/reopen a shell.  Will autocomplete any
# hosts found in known_hosts.

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | \
    sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh

Vous pouvez faire quelque chose de similaire en utilisant votre $HOME/.ssh/configfichier si, pour une raison quelconque, vous ne parvenez pas à trouver le fichier de règle de complétion pour sshdéjà pré-emballé.

slm
la source
Je vous remercie. Il semble que Ubuntu ne soit pas livré avec /usr/share/bash-completion/completions/ssh. Pourriez-vous poster ce fichier entier quelque part que je pourrais le copier? Merci!
dotancohen
Vous pouvez obtenir tous les fichiers de cette archive: pkgs.fedoraproject.org/repo/pkgs/bash-completion/…
slm
Je suis désolé d'être pénible, mais même copier le fichier ssh de cette archive tar /usr/share/bash-completion/completions/sshn'aide pas! L'exécution de la complete -W ...commande à partir de l'invite Bash non plus. Quel pourrait être le problème ici?
dotancohen
Je vous remercie. Cela semble être une décision de conception connue sous Ubuntu. Ainsi, j'accepte la réponse même si je ne parviens pas à terminer mon travail pour sshou scp.
dotancohen
2
Homebrew pour OSX a également ceci: bash-completion et zsh-completeions
Adam Nelson
7

J'ai constaté que l'auto-complétion ne fonctionnait pas car Ubuntu hachait des hôtes connus. Vous pouvez ajouter

Host *
    HashKnownHosts no

Pour votre .ssh/configfichier, mais les hôtes existants ne seront pas décomposés.

M1ke
la source
Je vous remercie. En fait, j'ai déjà ajouté ~/.ssh/configet modifié cette directive /etc/ssh/ssh_config, et j'ai supprimé le ~/.ssh/known_hostsfichier. Après avoir reconnecté les serveurs, les noms d’hôte sont toujours en cours de sauvegarde.
dotancohen
J'ai modifié ma réponse; vous devrez spécifier un hôte et imbriquer la directive hash à l'intérieur; Je n'ai pas indiqué que beaucoup de .ssh/configfichiers contiendraient déjà cette ligne. Faites-moi savoir si cela fonctionne.
M1ke
C'est certainement le moyen facile de le faire! Etant donné que (c’est le cas pour les versions plus récentes d’Ubuntu, l’achèvement de ssh est activé), c’est probablement ce que nous souhaitons.
John Montgomery le
Comme je l'ai ajouté ci-dessous, vous pouvez le faire, mais vous ne devriez probablement pas - vous n'avez pas besoin de le faire pour que votre travail fonctionne de toute façon. Cependant, si vous n'acceptez pas et que vous vouliez simplement supprimer le hachage des hôtes existants après avoir ajouté ce qui précède, vous pouvez simplement écrire ~ / .ssh / known_hosts, ce qui entraînera sa régénération (sans hachage) chaque fois que vous vous connectez à un nouveau serveur.
Jamieson Becker
3

Pour activer l'auto-complétion ssh dans Debian et Ubuntu:

sudo apt-get install bash-completion

Notez que cela n’a absolument rien à voir avec le hashage de known_hosts, contrairement à ce qui a été dit plus haut et à la question initiale. Si vous souhaitez compléter automatiquement à partir de known_hosts, vous devez bien sûr désactiver le hachage, mais cela est fortement déconseillé.

Par exemple, j'ai:

Host *
    HashKnownHosts yes

dans mon fichier .ssh / config et que l'auto-complétion ssh fonctionne toujours très bien contre les hôtes répertoriés dans .ssh / config et / etc / hosts. Vous devez ajouter l'hôte à .ssh / config comme l'OP a déclaré:

Hôte my-awesome-host Hostname the.real.host.name

(Vous pouvez également ajouter une entrée d'hôte à / etc / hosts, qui est une autre source pour les scripts Debian / Ubuntu.)

Ensuite, vous pouvez simplement taper ssh my-awe<tab>et il sera complété automatiquement. Encore une fois, cela se produit même si vous utilisez HashKnownHosts, ce qui est vivement recommandé. (Notez que l'achèvement de bash doit être activé dans votre shell bash et que ces scripts doivent être installés spécifiquement comme ci-dessus pour votre distribution.)

Ajoutez ensuite ces lignes à votre .bashrcpour l'activer (nécessite une déconnexion et une nouvelle connexion, ou tout simplement un nouveau bashsaisi pour lancer un nouveau shell. (Vous n'avez pas besoin d'activer s'il est déjà activé dans /etc/bash.bashrcet les /etc/profilesources /etc/bash.bashrc).

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Cela permettra autocomplétion ssh (entre autres!) De ~/.ssh/config, /etc/hostsetc.

Notez que Debian utilise par défaut cendré au lieu de bash. Vous pouvez passer à bash facilement:

sudo usermod -s /bin/bash "$USER"

(Vous devrez vous déconnecter et vous reconnecter pour que cela prenne effet.)

Jamieson Becker
la source
2

Sur Ubuntu 14.04, l’ sshauto-complétion des serveurs mentionnés dans votre~/.ssh/config

Je l'ai remarqué lorsque j'ai réalisé qu'un seul des serveurs auquel j'accède habituellement est rempli automatiquement. La seule différence entre les deux était une entrée dans le fichier de configuration ssh liée à l'authentification. Lorsque j'ai ajouté une nouvelle entrée au fichier de configuration pour l'autre serveur, la saisie automatique a également commencé.

Voici l'entrée pour ceux qui demandaient:

HOST server-name 
    GSSAPIAuthentication=no

Je serais très surpris si cela importait ce que vous spécifiez dans la configuration (tant que cela est toujours valable, bien sûr).

Noé
la source
Merci Noah, quelle était cette entrée? Sur mes systèmes 14.04 et 14.10, la complétion automatique ne fonctionne pas.
dotancohen
Je ne pense pas que l’entrée soit importante - je suis à peu près sûre que ce n’est que de les avoir là-dedans - mais je vais ajouter l’entrée à ma réponse.
Noah