スクリプトラッパ
先日のスクリプトラッパですが、himainuさんより、うまく動かない状況について報告がありました。
BusyBoxにはシェルもいくつかアプレットとして入ってます。たとえばashとか。
たとえばこのashをデフォルトで使うようにすると、/bin/shとして使えます。
$ pwd /tmp $ cat /bin/sh ← スクリプトラッパのsh #!/bin/busybox $ cat test.sh ← テスト用シェルスクリプト #!/bin/sh echo $* $ ./test.sh aaa bbb ccc ← シェルスクリプトの実行 aaa bbb ccc $
しかし、このシェルスクリプトをexecve(2)などの関数で呼び出すと、失敗します。
$ cat test.c #include#include int main(int argc, char **argv) { execv("/tmp/test.sh", argv); ← execvでシェルスクリプトを呼び出し return errno; } $ gcc -o test test.c $ ./test aaa bbb ccc ← 実行するが、何も表示されない $ echo $? 8 ← エラーとして"ENOEXEC"が返ってくる $
で、execveのmanpageを見直すと、「説明」のところに、
execve()は、filenameによって指定されたプログラムを実行する。filenameは、バイナリ実行形式か、"#! interpreter [arg]"という形式の行で始まるスクリプトでなければならない。後者の場合、interpreterは適切な実行ファイルのパス名でなければならず、それ自身がスクリプトであってはならない。そしてそれはinterpreter [arg] filenameの形で呼び出される。
ちゃんと書いてあるじゃないですか… orz
シェル以外はスクリプトラッパを使うことができますが、シェルについてはリンク(もしくはバイナリラッパ)を使う必要があるということです。
SELinuxでのドメイン分離
現在のところ、BusyBoxでスクリプトが使えるアプレットは、いくつかのシェルだけです。
ですので、BusyBoxを使うときに複数のシェルアプレットを使用しないという条件であれば、バイナリラッパなどは使用しなくても
- シェルのみ、/bin/busyboxにリンクし、他は"#!/bin/busybox"と書いたスクリプトラッパを利用する(/bin/shと/bin/busyboxは同じドメイン?)
- いっそのこと、/bin/busyboxを/bin/shにリネームする。他は"#!/bin/sh"と書いたスクリプトラッパを利用する(分かりにくい…)
という解決方法がありそうですね(どちらかというと前者でしょう)。