So-net無料ブログ作成

bash-completionを使ってみた。作ってみた。 [Linux]

いろんなディストリビューションにデフォルトで入っていると思われるbash-completion。bashを使っている際にコマンドラインでTabを押すとディレクトリの中身以外に選択肢を出して補完してくれる優れもの。使っているUbuntuにも入っていたけれど、Dockerのミニマムなコンテナイメージには含まれていなかったので、後で入れた。あるとないとじゃ大違い。

存在を知らなかった頃は、コマンド側でそういう仕組みを作っていると思っていたんだけど、実はbashの中で補完していたという事をわりと最近知った。それがbash-completionがやっている事もそう。C言語とかでやってるのかなと思っていたら、普通にシェルスクリプトでやっていたのでした。

 http://heartbeats.jp/hbblog/2013/06/bash-completion.html
 http://d.hatena.ne.jp/snaka72/20090930/1254316751
 http://www.usupi.org/sysad/236.html

具体的には、上のを見て自分でも書けそうだなと思ったりした。

/etc/bash_completion

の中身は

/usr/share/bash-completion/bash_completion

だって事で見てみると、serviceコマンドはそこに含まれていた。

外付けのコマンドは
/usr/share/bash-completion/completions/
に入っている。
/etc/bash_completion.d/
にも入ってるけど切り分けはわからない。
Dockerとかは後者の方に入っていた。


で、実際に書いてみた。というか既存の似たコマンドをパクった。
わたし的にはaptitudeとかapt-getとかが好きで少しわかっているのでそれなどを見た。
_hoge()
{
    local cur prev words cword
    _init_completion || return

    COMPREPLY=( $( compgen -W "foo bar nani sore" -- "$cur" ) )

}&&
complete -F _hoge hoge

普通の補完はTabを押すと、カレントディレクトリのファイルの一覧が出てくるんだけど、この場合はfoo bar nani soreが選択候補になります。このままではファイル選択の機能が死にますが、後で意図的に入れたい場合は、_filedirを呼び出せばいいみたい。

_hogeと実際の補完される方のコマンドのhogeは名前が一緒じゃなくていいのですが、慣習から同じくしているみたいですね。とりあえず最後の引数は実際に使えるコマンドじゃないと動かないですよね、当然。

キモとしてはcompgen -wで補完候補リストを作ってCOMPREPLYに入れて、それをcomplete -Fで実行しているという感じ。実はそれ以上でもそれ以下でもなさそう。_init_completionでcurにそれまで入力されたもの関係が入っているようなので指定しないと消えるんだったっけかな。

本当は_init_completionが実際何をしているとか見れば面白いのだろうけど、いかんせん暇がないのでシェルスクリプトが好きな人は見てください。あぁシェルスクリプトが好きな人は、こんなところ見に来ないで自分で探ってますよね、そうですよね。とりあえず他の補完方法で使いたいところがあれば、「completionsディレクトリから探してパクっちゃいなよ、YOU」ということで。

あと作る時にはbash -lでいちいち反映させてあげなくちゃいけないはず。ファイルを変更したのにどうにも反映されない時にはbash -lで更新されるはずです。もっといい方法があるのかもしれないけど、僕は何度もこのコマンドを打った。あと、気にすることってなかったかなぁ。とりあえず、上のスケルトンコードをいじるなり、他の既存のシェルスクリプトを改造するなりして割と簡単に作れますよ。まぁ大体のコマンドがすでに補完可能になっているので、使う側で良くて作らなくていい人がほとんどだと思うけど、また使う時用の備忘録ということで。

コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0