スクリプトラッパ

先日のスクリプトラッパですが、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を使うときに複数のシェルアプレットを使用しないという条件であれば、バイナリラッパなどは使用しなくても

という解決方法がありそうですね(どちらかというと前者でしょう)。