はじめに
タイトル通りです。これで1時間くらいハマりました。
原因が全く分からずムカついたのでメモ。
結論
- Shebangが無かった
-
#!/bin/bash
を指定する事
-
- systemdはシェルスクリプトの駆動にbashを使用していない
- 正規表現を使ったif文はshからは使えない
いきさつ
実行環境はRaspbian/Ubuntu 22です。他のディストリビューションだとどうなるかは知りません。
こんな現象が起きました。
- シェルスクリプト単体はbashから動く
- シェルスクリプトをsystemdから起動すると動かない
ループの中でif文に正規表現を使うだけのテストコードです。
終了するとサービスにならないので無限ループとしています。
test.sh
test=kusounkokuso
while :; do
if [[ ${test} == *unko* ]]; then
echo "oh yes"
fi
sleep 3600
done
シェルの出力はこう。予想通りの動作です。
$ ./test.sh
oh yes
サービスとして登録した場合のsystemctl status
の出力はこう。
× test.service - kuso
Loaded: loaded (/etc/systemd/system/test.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 200000024-01-01 00:00:00 JST; 10s ago
Process: 99999 ExecStart=/usr/bin/test.sh (code=exited, status=203/EXEC)
Main PID: 99999 (code=exited, status=203/EXEC)
CPU: 2ms
1月 01 00:00:00 shit systemd[1]: test.service: Scheduled restart job, restart counter is at 32.
1月 01 00:00:00 shit systemd[1]: Stopped kuso.
1月 01 00:00:00 shit systemd[1]: test.service: Start request repeated too quickly.
1月 01 00:00:00 shit systemd[1]: test.service: Failed with result 'exit-code'.
1月 01 00:00:00 shit systemd[1]: Failed to start kuso.
明らかにsystemdが原因ですがエラーメッセージの内容が無いので原因が良く分りません。
どうする
Shebangからbashを指定しました。
test.sh
+ #!/bin/bash
test=kusounkokuso
while :; do
if [[ ${test} == *unko* ]]; then
echo "oh yes"
fi
sleep 3600
done
systemctl status
の出力も正常です。プロセスツリーにbashがいる事に注目してください。
● test.service - kuso
Loaded: loaded (/etc/systemd/system/test.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 300000024-01-01 00:00:00 JST; 3s ago
Main PID: 99999 (test.sh)
Tasks: 2 (limit: 9239)
Memory: 528.0K
CPU: 4ms
CGroup: /system.slice/test.service
├─99999 /bin/bash /usr/bin/test.sh
└─999999 sleep 3600
1月 01 00:00:00 shit systemd[1]: Started kuso.
1月 01 00:00:00 shit test.sh[99999]: oh yes
修正後のシェルスクリプトをbashではなくshに突っ込みました。Shebangは無視されるようです。
$ sh ./test.sh
/usr/bin/test.sh: 3: [[: not found
おわりに
くだらねえーーーーーーー