web-dev-qa-db-ja.com

zshでsshのコマンド補完を編集する方法は?

入力後にホスト名を表示するようにzshでコマンド補完を設定したい

ssh [TAB]

私の.ssh/configファイルから(そしてできればknown_hostsと/ etc/hostsから、そして意味のある他の場所から)名前を取り出し、単一のリストを提示します。

現在、これの一部を実行していますが、

  1. .ssh/configをまったく使用しません
  2. .ssh/configを使用するとユーザー名の入力が不要になりますが、最初にユーザー名が必要です
  3. 複数のリストを表示します(おそらく1つはknown_hostsから、もう1つは/ etc/hostsからですが、確認していません)

Ssh [TAB]と入力した後、既知のユーザー名と既知のホスト名を(できれば単一の)リストに含めたい

(私がGoogleの前にここに来ているのは、1)回答がここに保存されるため、2)おそらくより効率的だからです。他に誰も答えない場合は、答えを探します。)

11
iconoclast

これが私の.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

ssh補完を提供する関数は、私のシステムの/usr/share/zsh/functions/Completion/Unix/_sshにあります。

ドキュメンテーションについてはman zshcompsysも参照してください(特に、複数の場所に表示される「ホスト」といくつかの場所に表示される「ssh」で検索してください)。

zstyleコマンドを~/.zshrcに追加すると、補完関数を変更しなくても、期待どおりの結果が得られる可能性があります。

Digを使用して、特定のドメイン上のすべてのホストのリストを使用してこれを行います。以下の関数を、hostsファイルまたは静的リストを含む任意の検索システムに置き換えることができます。

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を設定するだけです。

1
Caleb

ハッシュ化したままにするのが好き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
0
Karl Wilbur