キオスクモードで動作するようにDebianを設定しています。そのために、監視機能を実行するサービスを作成しました。
[Unit]
Description=Watchdog for myapp
[email protected]
After=polkit.service
After=udisks2.service
[Service]
ExecStartPre=systemctl stop dm
ExecStart=su user -c "startx /opt/myapp-watchdog.sh -- :0 vt7"
ExecStop=systemctl start dm
Type=simple
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=5
RuntimeMaxSec=infinity
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/user/.Xauthority"
Environment="XDG_VTNR=7"
[Install]
WantedBy=graphical.target
問題は、ExecStartがmyappから終了コードを取得するのではなく、startxから取得することです。多くのオプションを試しましたが、動作するオプションが見つかりません...
終了コードをパイプして&?を終了し、終了コードをファイルに書き込もうとしました。しかし、明らかに私のbash技術は正しいコマンドを実行するのに十分ではありません。
インターネット検索は、人々がユーザーではなくルートから直接呼び出す場合を見つけるのに役立ちませんでした。これが、終了コードが私の場合よりもはるかに簡単に送信される理由です。
答え1
調べました。この問題はstartxでは解決できません(証拠:gitlabのxserverエラーへのリンク)。私は自転車を発明し、杖を使用しなければなりませんでした。
解決策は、ソフトウェアにループ内で実行されているスクリプトをサービスで実行させることです。その後、ソフトウェアの終了コードを確認してください。コードが0の場合、スクリプトは操作を完了しました。それ以外の場合は、ループの次の繰り返しを開始します。以下のコードは、最初の緊急終了後の最後の瞬間にソフトウェアが5回以上間違って完了した場合にこのループを終了するメカニズムを実装しています。
サービスコード:
[Unit]
Description=Watchdog for myapp
[email protected]
After=polkit.service
After=udisks2.service
[Service]
ExecStartPre=systemctl stop dm
ExecStart=su user -c "startx /opt/myapp-watchdog.sh -- :0 vt7"
ExecStop=systemctl start dm
Type=simple
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=5
RuntimeMaxSec=infinity
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/user/.Xauthority"
Environment="XDG_VTNR=7"
[Install]
WantedBy=graphical.target
サービススクリプトコード:
#!/bin/bash
RETURN_VALUE="1"
RESET_COUNTER=0
RESET_COUNTER_TIME=0
TIME_NOW=0
echo "myapp-watchdog: myapp-watchdog started"
while [ $RETURN_VALUE != "0" ]
do
echo "myapp-watchdog: myapp started"
/opt/myapp
RETURN_VALUE=$?
TIME_NOW=$(date +"%s")
if [ $RETURN_VALUE == "0" ]
then
echo "myapp-watchdog: myapp exited with code 0"
echo "myapp-watchdog: myapp-watchdog finished"
exit 0
else
if [[ $TIME_NOW -gt $RESET_COUNTER_TIME ]]
then
RESET_COUNTER=0
fi
if [ $RESET_COUNTER == 0 ]
then
RESET_COUNTER_TIME=$TIME_NOW+60
fi
RESET_COUNTER=$((RESET_COUNTER + 1))
echo "myapp-watchdog: abnormal exit code detected. Current number of errors in the last minute: $RESET_COUNTER"
if [ $RESET_COUNTER == 5 ]
then
echo "myapp-watchdog: myapp exited with code 1"
echo "myapp-watchdog: myapp-watchdog finished"
exit 1
fi
fi
done