zshのcompletionで不便なのは、_shが変なふうに定義されているところ。PATHから実行ファイルを探してきて補完しようとする。で、実行ファイルがシェルスクリプトじゃなくてバイナリとかだったら実行できないわけだ。
私がわざわざ「sh xxx.sh」とするとき、xxx.shはPATHから探してきてほしいわけではなくて、カレントディレクトリにあるファイルを実行して欲しい。なのだが、TABで補完すると知らんコマンドがたくさん引っかかる。これは不便だ。
というわけで、以下の内容のファイルを/usr/local/share/zsh-completions/_shに配置する。
#compdef sh ksh bash _default
これで平穏は保たれた。しかしsh xxxでxxxをPATHから探してくる動作は酷くないか? Unixの歴史の闇…しかも、普通のコマンド実行と違って、カレントディレクトリが優先だ。
sh-3.2$ cd $(mktemp -d) sh-3.2$ ls -a . .. sh-3.2$ sh ls /bin/ls: /bin/ls: cannot execute binary file sh-3.2$ vi ls sh-3.2$ chmod +x ls sh-3.2$ ls ← /bin/lsが実行される ls sh-3.2$ sh ls ← ./lsが実行される hello
PATHから探して欲しけりゃ、わざわざ「sh」つけないでしょ、っていう。普通のインタプリタで実行するファイル名を指定する時は、そうだよ?
sh-3.2$ python pwd python: can't open file 'pwd': [Errno 2] No such file or directory