shebangを使ったスクリプトインタープリタ実行時の引数

結論: getoptだとshebang引数が上手く取れないから、自前でparseした。


/path/to/interpという、Cで書かれたスクリプトインタープリタを自分で書いたとする。
そして、

#!/path/to/interp --aaa=bbb --ccc=ddd -e
...
...
...

というファイル「opt.interp」があったとする。
これには実行権限がついている。
これは、

./opt.interp --xxx=111 --yyy=222 -z aaa

のように実行されるものとする。
この時、/path/to/interpには、どんなargvが渡されるのか。
これを、各パターンに分けてメモしておく。
(上記の例がどうなるかはメモの一番最後になる。)


まず、シェルから直接、

/path/to/interp --aaa=bbb --ccc=ddd -e

と実行した場合。
これは普通に、argvには、

{ "/path/to/interp", "--aaa=bbb", "--ccc=ddd", "-e" }

が入る。
これは普通にgetoptを使って分解できる。


次。
最初の例とは違い、以下のように、引数無しでshebang形式で書かれたスクリプトを実行した時。

#!/path/to/interp
...
...
...

このファイル名は「noopt.interp」という事にする。

./noopt.interp --xxx=111 --yyy=222 -z aaa

これを実行すると、argvには、

{ "/path/to/interp", "./noopt.interp", "--xxx=111", "--yyy=222", "-z", "aaa" }

が入る。
この末尾の引数の解釈は書かれたスクリプトが行うので、interpはこれをいじる必要は、普通はない。


最後。
最初の例の奴。
「opt.interp」。

#!/path/to/interp --aaa=bbb --ccc=ddd -e
...
...
...

これを引数を付けて実行する。

./opt.interp --xxx=111 --yyy=222 -z aaa

argvは以下のようになる。

{ "/path/to/interp", "--aaa=bbb --ccc=ddd -e", "./opt.interp", "--xxx=111", "--yyy=222", "-z", "aaa" }


結論。
まず、argvを見て、前述のどのパターンなのかを判別する(とりあえず自分はargv[1]がファイルとして存在するか見て判断するような実装にした)。
そして、最後のパターンだと分かったら、argv[1]を自前でparseしてから、getoptに渡す必要がある。
この時、ただ単に空白で区切ればいいというものでもなく、「--aaa="bbb ccc"」のような引数が出てくる可能性もある。
なんて面倒なんだ。


面倒なので、とりあえず空白でのみsplitするようにして、「引数には空白を含む値は使えません、仕様です」という事にした。