「-」の妙技(1)
2008.07.21
前回wgetのハイフンを使った小技(標準出力指定を「-O -」でする)を紹介しましたが、UNIXコマンドのオプションの細かい話....というと
そんなん知ってるだろ!
というノリで(かつて)は全然説明されず、今も
めちゃ細かいことまでは知らんよ
とほっておかれている雰囲気のあるネタについて話しましょうか。
これ実際にはですね、getopt(3) という有名なライブラリ(Linux だと GNU の実装がデフォ。正確には「長いオプション」を扱うのはその拡張である getopt_long(3))を、大概のUNIX基本コマンドが使って、ややこしくも大量なオプションを処理するのが基本なのです。ですから、 getopt(3) のルールをまず理解することが大切でしょう。 まず、コマンド引数は
- 1. パラメータのないオプション
- 2. パラメータのあるオプション
- 3. 操作対象(大概実在するファイル・非オプション)
の3つのカテゴリに分けるのがいいでしょう。
% command -S --single file1 file2
というコマンドラインの場合、「-S, --single」がパラメータのないオプションであり、file1, file2 が操作対象になります。このコマンドを見たとき、 file1 と file2 に対して、何か処理がされるけども、詳細な動作のオプショナルな指定が -S と --single によってされている と理解すればOKです。
オプションの指定方法には大概
- 1. 頻繁に使い、手っ取り早く指定するための短いオプション(
-S) - 2. 説明的で判りやすく、具体的な詳細に応じていくつでも作れる長いオプション(
--single)
の2通りがあり、一般に「長いオプション ⊃ 短いオプション」の関係になります。だったら「長いオプションだけ、でもいいのかも」と思うかも知れませんが、実は短いオプションの場合、「それを組み合わせて一発で指定する」という技があります(後述)。
また、オプション指定がそれ自身として完結せずに、何かオプションに対するパラメータが必要な時、どう指定するか...というと、
% command -O param --option=param file1 file2
といったかたちで書くことになります。オプションのパラメータは
- A. 短いオプションの場合は空白で区切って
- B. 長いオプションの場合は空白で区切るか、「=」でつないで
指定できます。先ほど述べた「短いオプションを合体させる」というと、こういう感じでよく使いますでしょ(長い表記=l、ファイル種別に応じて末尾に記号を付加する=F、「.」で始まる隠しファイルも表示する=a)。
% ls -lFa
これは、
% ls --format=long -classify -all
と長いオプションで表記することもできますけども(説明的なのがgoodなスクリプト内部だと、わざわざそうするメリットありますね)、
% ls -l -F -a
で分離して書いたとしても同じです(けど短い方がいいですね!)。 このときオプション・パラメータがあるのならば(-w,--widthは一覧表示幅を120文字に広げるので、マルチカラム表示の列数が変わると思う)、
% ls -aF --width=120
を、
% ls -aFw120
と合体最後のオプション・パラメータ(120)だけはそのまま引数に続けて書けば、引数付きオプションを指定できたりするのです。
で、あとヒジョーに有用、でも知らない人は知らない「オプション」として、 -- があります。これはですね、たとえば うっかり「-i」ってファイルを作っちゃって、そのファイルが消せない(% rm -i は問い合わせ付き削除のオプション指定)ことがありますが、実は
% rm -- -i
で消せます(ま、ワイルドカードうまく使って、 % rm ?i で消す手もあるけど)。つまり、「--」オプションは、 このオプション以降は、純粋に操作対象(非オプション)と見て、オプション解析をしない ことを伝えます。ですから、いくら格好がオプションでも、それは操作対象(実在するファイル)と捉えてうまく削除ができるわけですね!
としてみるとですね、実は逆に -- オプションが出ないのならば、操作対象とオプションは、必ずしもオプションが先、操作対象が後、である必要はない! ということになります(とはいえ「プログラムでのこのライブラリの使い方」でこれは変わることがあります)...これ UNIX の風習とは少し違う気がしますから、 フツーはオプションが先、操作対象が後できっちり分けておく のがどっちか言えば常識だと思います。しかし、そうじゃない扱いもできますよ...というのがこの getopt(3)の懐の深いところなのかもしれません。
ですから、たまにある + を「特殊なオプションとして使う」コマンド(date, head)だって、このgetopt(3) を使うことができますし、あるいは昔の cc が、 リンク順指定の都合で、リンクライブラリ指定(-l)をコマンドラインの一番最後にもってこないといけない... というような特殊ケースにもちゃんと対応できるわけです。
ま、今時はそうしなくても共有ライブラリのおかげでリンク順が無関係になりましたが、Makefile とかでは非共有ライブラリOS対応も兼ねて、今でも一番最後に -l を書いてますよね....
長くなってきたので、「標準出力を表すハイフン」については別稿で。
投稿者 : 杉浦 こずえ | 投稿日時 : 2008.07.21 11:28
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





