Nomi server di completamento automatico per SSH e SCP


61

Ho configurato alcuni server ~/.ssh/config, come alphae beta. Come potrei configurare Bash in modo tale che i comandi ssh al<tab>e il scp file.tgz al<tab>completamento automatico dei nomi dei server configurati?

Non voglio aggiungere i server a un altro file (ad esempio un array Bash) ogni volta che uno viene aggiunto, poiché aggiungiamo e rimuoviamo regolarmente i server e l'elenco è piuttosto grande.


2
Hai installato il pacchetto bash-completions per la tua distribuzione? Penso che questo faccia parte delle routine di completamento standard, anche se potrei confonderlo con zsh.
Caleb,

La mia installazione fa esattamente questo.
slm

Questo è su Kubuntu 12.10 e l'ho bash-completioninstallato.
dotancohen,

Risposte:


64

Trovato!!

Sembra che in Ubuntu le voci in ~/.ssh/known_hostssiano sottoposte a hash , quindi il completamento di SSH non può leggerle. Questa è una funzione, non un bug. Anche aggiungendo HashKnownHosts noa ~/.ssh/confige /etc/ssh/ssh_confignon sono stato in grado di impedire l'hash dell'host.

Tuttavia, si trovano anche gli host a cui sono interessato ~/.ssh/config. Ecco uno script per il completamento di Bash che legge le voci da quel file:

_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

Inserisci quello script /etc/bash_completion.d/sshe quindi procedi con il seguente comando:

$ . /etc/bash_completion.d/ssh

Ho trovato questa guida preziosa e non avrei potuto scriverla senza di essa. Grazie Steve Kemp per aver scritto quella fantastica guida!


1
Sembra che in Centos 6 voci in ~ / .ssh / known_hosts sovrascrivano le voci in ~ / .ssh / config ad es. se disponi di foo.bar.baz.com in known_hosts, corrisponderà a tutto se fai "ssh foo" <tab> - questo è indesiderabile se hai un utente diverso o altre impostazioni che desideri vengano applicate dal config ssh. Se hai una voce in ssh config che non si completa automaticamente, controlla se è presente in known_hosts ed eliminala. Ora dovrebbe funzionare normalmente prendendo le impostazioni dalla configurazione.
Imran-UK,

@ Imran-UK: È noto che Ubuntu non fa quella cosa sensata, con la scusa della sicurezza. Apparentemente il pensiero è che un'entità malevola potrebbe, come l'utente, modificare ~ / .ssh / config, nonostante chmod 0600 nella directory. Ehi, non sono stato io a prendere la decisione!
dotancohen,

1
Uso zsh & oh-my-zsh, ho appena scoperto che abilitare il plug-in "ssh" e inserire "HashKnownHosts yes" nel mio ~ / .ssh / config sembra fare la cosa giusta. Puoi cambiare shell qualunque sia la distribuzione, quindi questo potrebbe essere un modo per aggirarlo.
Imran-UK,

@ Imran-UK: In effetti ho provato zsh in passato e ho intenzione di riprovare. Lo esaminerò. Shukran, amico mio!
dotancohen,

So di essere un po 'in ritardo alla festa, ma RHEL 7 completerà automaticamente le voci presenti /etc/hosts, altre distro potrebbero fare lo stesso.
Centimane,

16

Pre-confezionati

Non dici quale distro stai usando, ma sul mio sistema Fedora 19 ho installato il seguente pacchetto, bash-completionche fornisce questa funzione attraverso questo file delle regole di completamento:

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

Ecco il pacchetto che ho installato:

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

Se guardi attraverso quel file di regole vedrai stanze che stanno interrogando il $HOME/.ssh/configfile:

$ 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"

Rotolare il tuo

Ho anche trovato questo Gist, known_hosts_autocomplete.sh , che fa qualcosa di simile tranne che con il $HOME/.ssh/known_hostsfile.

# 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

Puoi fare qualcosa di simile usando il tuo $HOME/.ssh/configfile se per qualche motivo non riesci a trovare il file della regola di completamento per sshgià preconfezionato.


Grazie. Sembra che Ubuntu non venga fornito con /usr/share/bash-completion/completions/ssh. Potresti pubblicare l'intero file da qualche parte che potrei copiarlo? Grazie!
dotancohen,

Puoi ottenere tutti i file da questo archivio: pkgs.fedoraproject.org/repo/pkgs/bash-completion/…
slm

Mi dispiace essere una seccatura, ma nemmeno copiare il file ssh da quell'archivio tar /usr/share/bash-completion/completions/sshnon aiuta! Né esegue il complete -W ...comando dal prompt di Bash. Quale potrebbe essere il problema qui?
dotancohen,

Grazie. Questa sembra essere una decisione di progettazione nota in Ubuntu. Quindi sto accettando la risposta anche se non riesco a far funzionare il completamento bash per ssho scp.
dotancohen,

2
Homebrew per OSX ha anche questo: bash-completamento e zsh-completions
Adam Nelson,

7

Ho scoperto che il completamento automatico non funzionava perché Ubuntu esegue l'hashing di host noti. Puoi aggiungere

Host *
    HashKnownHosts no

Nel tuo .ssh/configfile, ma gli host esistenti non verranno cancellati.


Grazie. In realtà ho già aggiunto questa direttiva ~/.ssh/confige modificato la direttiva in /etc/ssh/ssh_config, e ho rimosso il ~/.ssh/known_hostsfile. Dopo aver effettuato nuovamente l'accesso ai server, i nomi host vengono ancora salvati con hash.
dotancohen,

Ho modificato la mia risposta; dovrai specificare un host e annidare la direttiva hash all'interno; Non ho elencato che molti .ssh/configfile avranno già questa linea. Fammi sapere se funziona.
M1ke

Questo è sicuramente il modo più semplice per farlo! Dato che (le versioni più recenti di) Ubuntu ora hanno abilitato il completamento ssh, questo è probabilmente ciò che si desidera.
John Montgomery,

Come ho aggiunto di seguito, puoi farlo, ma probabilmente non dovresti - non è necessario per far funzionare comunque il completamento. Tuttavia, se non si è d'accordo e si desidera semplicemente annullare la hash degli host esistenti dopo averlo aggiunto sopra, è possibile semplicemente rm ~ / .ssh / known_hosts e ciò causerà la rigenerazione (senza hash) ogni volta accedi a un nuovo server.
Jamieson Becker,

3

Per abilitare il completamento automatico ssh in Debian e Ubuntu:

sudo apt-get install bash-completion

Si noti che ciò non ha assolutamente nulla a che fare con l'hashing di known_hosts, contrariamente a quanto affermato sopra e alla domanda originale. Se vuoi completare automaticamente da known_hosts, ovviamente dovresti disabilitare l'hash, ma è fortemente sconsigliato.

Ad esempio, ho:

Host *
    HashKnownHosts yes

nel mio .ssh / config, e ho ancora il completamento automatico di ssh che funziona perfettamente con gli host elencati in .ssh / config e / etc / hosts. È necessario aggiungere l'host a .ssh / config come indicato dall'OP:

Ospita my-awesome-host Nome host the.real.host.name

(Oppure, puoi aggiungere una voce host a / etc / hosts, che è un'altra fonte per gli script Debian / Ubuntu.)

Quindi, puoi semplicemente digitare ssh my-awe<tab>e verrà completato automagicamente. Ancora una volta, questo è anche se HashKnownHosts, che è altamente raccomandato. (Nota che il completamento della bash deve essere abilitato nella tua shell bash e devi avere specificamente quegli script installati come sopra per la tua distribuzione.)

Quindi, aggiungi queste righe al tuo .bashrcper abilitarlo (richiede un logout e il login di nuovo, o solo un nuovo bashdigitato per lanciare una nuova shell. (Non è necessario abilitare se è già abilitato /etc/bash.bashrce /etc/profilefonti /etc/bash.bashrc).

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

Ciò consentirà l'autocompletamento SSH (tra le altre cose!) Da ~/.ssh/config, /etc/hosts, ecc

Si noti che Debian per impostazione predefinita è ash anziché bash. Puoi passare facilmente a bash:

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

(È necessario disconnettersi e riconnettersi affinché questo abbia effetto.)


2

Su Ubuntu 14.04, sshcompleta automaticamente i server menzionati nel tuo~/.ssh/config

L'ho notato quando mi sono reso conto che solo uno dei server a cui accedo comunemente è stato completato automaticamente. L'unica differenza tra i due era una voce nel file di configurazione ssh relativa all'autenticazione. Quando ho aggiunto una nuova voce al file di configurazione per l'altro server, ha iniziato anche il completamento automatico.

Ecco la voce per coloro che chiedevano:

HOST server-name 
    GSSAPIAuthentication=no

Sarei molto sorpreso se importasse ciò che stavi specificando nella configurazione (purché sia ​​ancora valido, ovviamente).


Grazie Noah, cos'era quella voce? Sui sistemi 14.04 e 14.10 il completamento automatico non funziona.
dotancohen,

Non credo che la voce sia importante - sono abbastanza sicura che li abbia solo lì dentro - ma aggiungerò la voce alla mia risposta.
Noah,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.