基本的にこれを実行しているbashスクリプトを取得しました。
#!/bin/bash
[...]
while true; do
str="broadcast "`randArrayElement "messages[@]"`
server_send_message $str
sleep $interval
done
これをsystemdサービスとして実行したいのですが、サービススクリプトは次のようになります。
[Unit]
Description=Announcer
After=network.target
[Service]
ExecStart=/usr/local/bin/somescript &; disown
ExecStop=/usr/bin/kill -9 `cat /tmp/somescript.pid`
Type=forking
PIDFile=/tmp/somescript.pid
[Install]
WantedBy=default.target
残念ながら、service somescript start
を介してこのサービスを実行すると機能しますが、while trueループが原因で、端末がスクリプトの開始でスタックします。
● somescript.service - somescript service
Loaded: loaded (/etc/systemd/system/somescript.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2016-08-17 12:22:34 CEST; 43s ago
Control: 17395 (somescript)
CGroup: /system.slice/somescript.service
├─17395 /bin/bash /usr/local/bin/somescript &; disown
└─17409 sleep 600
「starting」/ while trueループで立ち往生することなく、このスクリプトをサービスとして実行するにはどうすればよいですか?
Systemdを動作させる必要があります。開始時の分岐とプロセスの終了を処理します。たとえば、サービス部品を
[Service]
Type=simple
ExecStart=/usr/local/bin/somescript
PIDFile=/tmp/somescript.pid
次に、systemctl start
、status
およびstop
。 systemdの行は、シェルによって解釈される[〜#〜] not [〜#〜]であることを覚えておく必要があります。たとえば、&;
は、2文字の別のパラメーターとしてスクリプトに渡されるだけです。
要件に応じて、ループをsystemdタイマー構成に置き換えることを検討できます。 server_send_messageが "OnUnitActiveSec"より長くかかっても、サービスを2回開始しません。
somescript.timer
[Unit]
Description=Announce every minute
[Timer]
OnUnitActiveSec=1m
AccuracySec=10s
Unit=somescript.service
[Install]
WantedBy=default.target
somescript.serviceサービス部分:
[Service]
Type=oneshot
ExecStart=/usr/bin/sh -c 'str="broadcast "`randArrayElement "messages[@]"`; server_send_message $str'