Я хотел бы настроить завершение команд на zsh для отображения имен хостов после того, как я наберу
ssh [TAB]
взяв имена из моего файла .ssh / config (и желательно из known_hosts и / etc / hosts и любого другого, что имеет смысл) и представил один единственный список.
В настоящее время он делает кое-что из этого, но
Поэтому я хочу, чтобы в список (желательно один) были включены известные имена пользователей, а также известные имена хостов после ввода ssh [TAB]
(Я прихожу сюда раньше, чем Google, потому что 1) это приведет к тому, что ответ будет сохранен здесь, и 2) это, вероятно, более эффективно. Если никто не ответит, я найду ответ.)
Вот соответствующая часть из моих .zshrc
. Он не менялся с 2002 года, поэтому сегодня я могу написать его по-другому, но он по-прежнему работает для завершения имен хостов из ~/.ssh/config
и ~/.ssh/known_hosts
(если HashKnownHosts
выключен - его тогда не было).
h=()
if [[ -r ~/.ssh/config ]]; then
h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ -r ~/.ssh/known_hosts ]]; then
h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null
fi
if [[ $#h -gt 0 ]]; then
zstyle ':completion:*:ssh:*' hosts $h
zstyle ':completion:*:slogin:*' hosts $h
fi
Я делаю это, используя список всех хостов в данном домене, используя dig. Вы можете заменить приведенную ниже функцию любой системой поиска, которая вам нужна, включая файл хостов или статический список:
function complete_host_from_zone () {
reply=(`dig axfr ouraynet.com @ns1.ouraynet.com | grep -e '^[a-z]' | cut -d\. -f1`)
}
compctl -x 'p[1]' -K complete_host_from_zone -- ssh
Примечание: Приведенный выше код может не полностью заменить всю систему для команды ssh в вашей конфигурации. Если у вас есть проблемы с этим, попробуйте заменить команду «ssh» на какую-нибудь другую случайную команду, например «mycompletetest», и посмотрите, работает ли для этого завершение.
Также обратите внимание, что это выполняет передачу зоны DNS при каждом завершении! Если вы используете это часто или в довольно статическом домене, имеет смысл выполнить поиск и сохранить результат, тогда в вашей функции поиска просто установите reply = zone_result.
Функция, обеспечивающая ssh
завершение находится по адресу /usr/share/zsh/functions/Completion/Unix/_ssh
в моей системе.
Также см man zshcompsys
для документации (особенно выполните поиск по «host», который появляется в нескольких местах, и «ssh», который появляется в нескольких местах).
Возможно, добавление zstyle
команда вашему ~/.zshrc
будет делать то, что вы ищете, не изменяя функцию завершения.
Мне нравится хранить хеш known_hosts
файл и предпочел бы не поворачивать HashKnownHosts
выкл. Я обнаружил, что добавление того, что есть у @Gilles, к тому, что уже есть в моей истории, было довольно эффективным для моих нужд.
h=($(echo $(history | awk '{print $4 " " $5 "\n"}' | grep 'ssh ' | awk '{print $2}' | sort -u)))
if [[ -r ~/.ssh/config ]]; then
h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ -r ~/.ssh/known_hosts ]]; then
h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null
fi
if [[ $#h -gt 0 ]]; then
zstyle ':completion:*:ssh:*' hosts $h
zstyle ':completion:*:slogin:*' hosts $h
fi
Кроме того, FWIW, это то, что я использовал для Bash:
# SSH Autocompletion
complete -W "
$(echo $(grep '^\s*ssh ' ~/.bash_history | sort -u | sed 's/^ssh //' | awk '{print $1}'))
$(echo $(history | awk '{print $2 " " $3}' | grep 'ssh ' | awk '{print $2}' | sort -u))
$(sed 's/#.*//;' ~/.ssh/config | awk ' /^Host (.+)$/ {$1 = "";print tolower($0)}')
" ssh