daemontools でハマったことと、その回避策の共有です。
※(追記) daemontools に限った話ではなかったので、タイトル変えました。
動作環境
- CentOS 6.2
エラー発生状況
/service/app-foo/run
は以下の内容:
#!/bin/sh
exec 2>&1
set -e
exec sh -c 'exec \
setuidgid app \
/home/app/foo/start
'
/home/app/foo/start
は以下の内容:
APP_ROOT="/home/app/foo"
source /etc/profile.d/rbenv.sh
cd $APP_ROOT
bundle install
exec bundle exec foo
(追記)
今回のエラーは、以下のようなもっと単純なスクリプトでも再現しました。
echo foo
正常に動作する操作
以下は期待通り動作します。
- app ユーザで
/home/app/foo/start
をシェルから実行 - 同 app ユーザで
sudo /home/app/foo/start
をシェルから実行
エラーになる操作
% sudo /service/app-foo/run
setuidgid: fatal: unable to run /home/app/foo/start: exec format error
% sudo sh -x /service/app-foo/run
+ exec
+ set -e
+ exec sh -c 'exec \
setuidgid app \
/home/app/foo/start
'
setuidgid: fatal: unable to run /home/app/foo/start: exec format error
sudo svc -u /service/app-foo
しても上がりません。
同じエラーが multilog に吐かれ続けます。
回避策
/home/app/foo/start
に shebang #!/bin/sh
を足しました。
この結果、run
スクリプトの手動実行も、daemontools 経由の起動もできるようになりました。
めでたしめでたし。
原因についての推測
setuidgid
経由だとシェルスクリプトを適当に解釈することができなくなるようです。
shebang をつけなくても、上記の run
スクリプトから setuidgid app
を外したところ、run
スクリプトを手動実行することができました。
setuidgid
をつけてスクリプトを動かす場合、shebang が必要になると思われます。