Функция автозаполнения Bash для SSHing в разных хостах

8

У меня есть большой список серверов, которые я обычно sshна все время. Есть ли способ использовать bashили zshтак, чтобы я мог сохранить список имени хоста, и автозаполнение bash проходит через файл и дает мне подсказку для полей, начинающихся с этих букв, всякий раз, когда я набираю первые несколько букв имени хоста.

pradeepchhetri
источник

Ответы:

8

ZshЗавершение работы с так называемыми ssh закладками. Это конфигурации для каждого хоста в ~/.ssh/config.

Например,

  host baz
    hostname 192.168.1.2
    port 22
    user warrick

  host bar
    hostname example.com
    port 2200
    user kevin
    identityfile /home/warrick/.ssh/ec2.pem

man ssh_config чтобы увидеть полный список вариантов.

РЕДАКТИРОВАТЬ

Я использую скрипт завершения из ohmyzsh :

https://raw.github.com/robbyrussell/oh-my-zsh/master/lib/completion.zsh

В похожем стиле ohmyzsh, я поместил вышеупомянутый скрипт в ~/.zsh/libs/completion.zshи добавил это к ~/.zshrc.

# ~/.zshrc
for f in ~/.zsh/libs/*; do
  source $f
done
kwarrick
источник
Я не использую zsh, но bash ...
Gilles Quenot
Правильно, вопрос об OPs касается bash или zsh, мой комментарий к вашему посту состоял в том, чтобы просто добавить ~ / .ssh / config к / etc / hosts, если это вообще возможно, что, согласно его вопросу, возможно при использовании zsh.
kwarrick
6

Скопировано из моего собственного ответа на unix.SE :

Если вы находитесь на хосте Ubuntu, то вы должны знать, что в Ubuntu записи в ~/.ssh/known_hostsхэше хэшированы , поэтому SSH-завершение не может их прочитать. Это особенность, а не ошибка. Даже добавив HashKnownHosts noк ~/.ssh/configи /etc/ssh/ssh_configя не смог предотвратить хозяина хэширования.

Однако вы можете прочитать настроенные записи ~/.ssh/config, которые не хэшированы. Вот скрипт для Bash Completion, который читает записи из этого файла:

_ssh() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(grep '^Host' ~/.ssh/config | awk '{print $2}')

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

Поместите этот скрипт, /etc/bash_completion.d/sshа затем отправьте его с помощью следующей команды:

$ . /etc/bash_completion.d/ssh

Я нашел это руководство бесценным, и я не смог бы написать это без него. Спасибо Стиву Кемпу за написание этого потрясающего руководства!

dotancohen
источник
2
+1, но я бы заменил строку awk на, opts=$(grep '^Host' ~/.ssh/config | sed 's@^Host @@')потому что ~/.ssh/configсинтаксис допускает несколько имен в одной строке
nhed
@nhed: Спасибо! Я не знал, что было разрешено.
dotancohen
0

Чтобы это работало, поместите все хосты, которые хотите завершить, в свой /etc/hosts файл .

Вам также нужен bash-completionпакет (содержащий файл / etc / bash_completion и каталог /etc/bash_completion.d)

и . /etc/bash_completionотправьте его в ~ / .bashrc ( иногда это закомментировано в /etc/bash.bashrc или в ~ / .bashrc).

Жиль Квено
источник
4
Я бы рекомендовал не использовать / etc / hosts. Вместо этого добавьте так называемые закладки ssh в ~ / .ssh / config. man ssh_configдля более подробной информации, но он гораздо более универсален, позволяя вам указать несколько псевдонимов, имя пользователя, порт и многое другое.
kwarrick
С archlinux, когда я что-то вставляю /etc/ssh/ssh_config, у меня нет завершения работы с настроенными хостами.
Жиль Квено
Смотрите мой расширенный ответ, я использую завершение из ohmyzsh.
kwarrick
1
Если вы посмотрите на источник , вы увидите, что скрипт проверяет known_hostsтак же, как и другие файлы конфигурации, например,~/.ssh/config
jasonwryan