2002-06-24

_ [url] Last 1 Hour - 私が"Cool"を疑う理由

なぜだか最初「会社を辞めるまえの1時間で書けるコラム」だと思ってしまった……

_ [url] developer's guide to security updates

めもめも。

_ [prog] .ssh/config に書いてあるホスト名を補完したい

zsh では ssh や ping 等の引数に /etc/hosts に書いてあるホスト名を補完してくれるが、普通 ssh でログインしたりするホストが書いてあることは少ない。

と言うわけで、.ssh/config に書いてあるホスト群も補完可能にしてみる。最初は perl を使ってやっていたのだが、これだとかなり遅い。キャッシュするから最初だけとはいえ、やっぱり遅い! と言うわけで、zsh の変数置換機能だけを使って書き直しに挑戦。

${${${(M)${(s:# :)${(zj:# :)${(Lf)"$([[ -f ~/.ssh/config ]] && <~/.ssh/config)"}%%#*}}##host(|name) *}#host(|name) }/*}

結局 parse 部分がこうなった。先行する空白を切るためにかなりダサイ事をやっているが、他に方法が思い付かない。

我ながら呪文だともうけど。「本当にこんなので parse 出来るのかッ?」と思ったら、上のやつを echo してみて下さい

* 今後も役に立ちそうなポイントは幾つか

  • ${(s:str:)var}, ${(j:str:)var}

var を str で分割/結合。- ${(z)var}

var を shellの分割文字で分割する- ${(f)"$(<filename)"}

で、filename 読み込み、改行で分割する。f は s:\n: と同じ。- ${(M)var:#pattern}

は grep みたいに使える。"#" でなくても "##" や "%" 等でも良い。

* と言うわけで

完成版。使ってみるとやはりスピードが結構違う……

* 実際に使うには

autoload する場合。

  • ~/lib/zsh/functions とかを作って、そこにファイルを置く。- ~/.zshrc 等で、fpath=(~/lib/zsh/functions $fpath) として、パスを先に通しておく。- ~/.zcompdump を消して キャッシュをクリア。- zsh を再起動

全部 ~/.zshrc で指定する場合。

hosts=( ${(@)${${(M)${(s:# :)${(zj:# :)${(Lf)"$([[ -f ~/.ssh/config ]] && <~/.ssh/config)"}%%#*}}##host(|name) *}#host(|name) }/*} )

zstyle ':completion:*:hosts' hosts $hosts