Die Tab-Vervollständigung für Hosts, die in ~/.ssh/config definiert sind, funktioniert auf Yosemite nicht mehr

Ich versuche, meine ~/.ssh/configDatei zu erstellen, um mein Arbeitsleben auf der Serververbindung zu vereinfachen.

In Mavericks funktionierte alles einwandfrei und mit dem tabkonnte ich den Hostnamen mit einer Datei wie dieser automatisch vervollständigen:

Host test-host-name
    HostName 192.168.1.2
    User root

Die gleiche Konfiguration auf Yosemite hat ein anderes Verhalten. Wenn ich ssh tauf der Shell tabeingebe, wird der Hostname nicht automatisch vervollständigt.

Weiß jemand, ob sich in Yosemite etwas geändert hat und ich jetzt etwas tun muss, damit es funktioniert?

Antworten (8)

Sie können die Bash-Shell-Vervollständigung aktivieren, indem Sie bash-completionüber brew installieren :

brew install bash-completion

Fügen Sie dann Folgendes zu Ihrer hinzu ~/.bash_profile:

if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi

Quelle

(Bearbeiten: brew tap homebrew/completionsist seit 2018 veraltet.)

+1 :) Bei der Installation von bash-completion-1.3.3.high_sierra wird mir mitgeteilt, dass ich [ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion. Könnten Sie erläutern, welche Version (diese oder Ihre) bevorzugt werden sollte und warum?
@JanNash Das ist im Grunde eine einzeilige Version davon if. Außerdem $(brew --prefix)wird es funktionieren, wenn Ihr Hombrew nicht auf installiert wird /usr/local. Sie sollten die gepostete Version als Antwort verwenden.
Dies funktioniert nicht auf meinem M1 Mac.

Ich nehme an, die Shell Ihres Mac ist Bash.

Sie müssen den ssh-Befehl abschließen, für weitere Details können Sie lesenman complete

_complete_ssh_hosts ()
{
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        comp_ssh_hosts=`cat ~/.ssh/known_hosts | \
                        cut -f 1 -d ' ' | \
                        sed -e s/,.*//g | \
                        grep -v ^# | \
                        uniq | \
                        grep -v "\[" ;
                cat ~/.ssh/config | \
                        grep "^Host " | \
                        awk '{print $2}'
                `
        COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
        return 0
}
complete -F _complete_ssh_hosts ssh

Vergessen Sie nicht, dass Sie sourcedie Datei benötigen, um den neuen Befehl in Ihr Terminal zu laden. oder Sie können diesen Code in .bash_profile einfügen

Ja, die Shell ist bash. Warum in Maveriks musste ich diese Dinge nicht tun?
Nein, ich habe gerade getestet. In Mavericks geht das standardmäßig nicht.
comp_ssh_hosts=$(awk -F , 'FNR== NR && ! /^#|\[/ {field = $1} FNR != NR && /^Host / {field = $2} {hosts[field]} END {for (host in hosts) {print host}' "$HOME/.ssh/known hosts" "$HOME/.ssh/config")
Ein kurzer Tipp: Dieser Befehl findet Ihren Host nicht, wenn Sie Tabulatoren anstelle von Leerzeichen verwenden. Wenn Sie also Ihre .ssh/config-Datei einrücken, behalten Sie dies im Auge
Ich erhalte eine Fehlermeldung .bash_profile:21: command not found: completeauf dem M1 Mac

Aus diesem Artikel auf MacWorld .

Folgendes kopieren/einfügen in ~/.bash_profile:

complete -o default -o nospace -W "$(/usr/bin/env ruby -ne 'puts $_.split(/[,\s]+/)[1..-1].reject{|host| host.match(/\*|\?/)} if $_.match(/^\s*Host\s+/);' < $HOME/.ssh/config)" scp sftp ssh

Sie müssen dann entweder Ihr Terminal neu starten oder tippen source ~/.bash_profile(beachten Sie, dass letzteres nur in Ihrem aktuellen Tab funktioniert).

Hat bei mir nicht funktioniert. Aber apple.stackexchange.com/a/168168/136365 tat es. Ich denke, es ist am besten, sich bei so etwas nicht auf Ruby zu verlassen.

Zu Ihrer Information, ich bin mir nicht sicher, wie ich direkt auf Nelsons Antwort antworten soll, da ich noch nicht genug Reputation aufgebaut habe, um sie zu kommentieren, aber auf meinem Computer, auf dem El Capitan ausgeführt wird, ^Mwurde an alle Hostnamen aus meiner Konfigurationsdatei angehängt . Ich musste entweder \rzu meiner Variablen hinzufügen oder alle Instanzen von aus der Ausgabe der zweiten $IFSentfernen/ersetzen . Am Ende habe ich letzteres getan, indem ich hinzugefügt habe, dass diese Befehlskette so aussieht:\rcattr '\r' '\n'

cat ~/.ssh/config | \
        grep "^Host " | \
        awk '{print $2}' | \
        tr '\r' '\n'

Nelsons Antwort (oben) sagt Ihnen nicht, welche macOS-Version er verwendet.

Für macOS 10.14 nach der Installation bash-completionmit:

brew install bash-completion

Das Installationsprogramm sagte mir, ich solle diese Zeile zu meinem .bash_profile hinzufügen (das ich stattdessen in mein .profile eingefügt habe) und es hat funktioniert:

  [[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"

Wenn Sie MacPorts verwenden :

$ sudo port install bash-completion

Fügen Sie dann Folgendes zu Ihrem ~/.bash_profile hinzu:

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

Vorhandene Antworten erscheinen mir wie Hacks. Der richtige Weg ist, OpenSSH mit editline/readline/history-Unterstützung zu kompilieren, so einfach ist das!

Ehrlich gesagt, kann ich unmöglich nachvollziehen, WARUM eine vernünftige Person es ohne dies gebaut hätte, da es alle wünschenswerten Funktionen (Aufwärtspfeil-Befehlsverlauf, Tab-Vervollständigung lokaler und entfernter Dateinamen usw.) ohne Einschränkungen bietet. Ich habe es aktiviert, als ich OpenSSH 8.7p1 auf meinem iPad mit Jailbreak erstellt habe, aber ich bin sicher, dass es überall gleich gut funktioniert.

Sie können Einträge in /etc/hosts hinzufügen und sie bei der automatischen Vervollständigung des Hostnamens verwenden:

"ssh @" + [TAB]

Ein Neustart ist erforderlich, damit das System diese Datei neu laden kann.