web-dev-qa-db-ja.com

zsh:sshの補完ルール

zshでは、/etc/hostsからホスト名をオートコンプリートできます。つまり、

ssh f<TAB>

fで始まるホストの補完を提供します。

これは/usr/share/zsh/functions/Completion/Unix/_hostsで設定されます:

local ipstrip='[:blank:]#[^[:blank:]]#'

zstyle -t ":completion:${curcontext}:hosts" use-ip && useip=yes
[[ -n $useip ]] && ipstrip=
if (( ${+commands[getent]} )); then
  _cache_hosts=(${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null)"}##${~ipstrip}}})
else
  _cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##${~ipstrip}}})
fi

....

_hosts=( "$_cache_hosts[@]" )

ただし、/etc/hostsファイルの形式が「IP」「ホスト名」の場合にのみ機能します。つまり、

192.168.1.4      foo.mydomain.com

iPがない場合は機能しません。

                 foo.mydomain.com

IPなしのホスト名も補完されるように、補完スクリプトを変更するにはどうすればよいですか?

/etc/hostsからのIPなしのホスト名の補完は、bash_completionで正常に機能します。したがって、私はzshで同じ動作を取得しようとしています。

4
400 the Cat

/usr/share/zsh/functions/Completion/Unix/_hostsにフィルター関数を追加します。

provide_missing_ip() {
   while read x ; do 
      set -- $x
      if [ ! "$1" ] || [ "${1%%[^#]*}" ] || [ "$2" ] ; then
          echo "$x"
      else
          ip=`Dig +short $2`
          [ "$ip" ] || ip="240.0.0.0"
          printf "%s\t%s\n" $1 $2
      fi
   done
}

使い方:

  1. 2つのエントリ、空白、またはコメントがある場合は、それらを出力します。
  2. ホスト名しかない場合は、[〜#〜] ip [〜#〜]アドレスにDigを付けて指定してください。
  3. 失敗した場合(これは起こりませんですが、テスト目的で意図的に偽のホスト名であるとしましょう)、無害なダミーを使用します[〜#〜 ] ip [〜#〜]240.0.0.0」のアドレス、(- Bandrami's/ dev/nullと同等のIPアドレス」 )に対する回答.

新しい関数を使用して、面倒な完了コードのgetentまたは< /etc/hostsの出力を解析します。

if (( ${+commands[getent]} )); then
  _cache_hosts=(${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null | provide_missing_ip )"}##${~ipstrip}}})
else
  _cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(provide_missing_ip </etc/hosts)"}%%\#*}##${~ipstrip}}})
fi
0
agc