systemctl stop
いくつかのサブコマンドを使用してシェルスクリプトを実行しようとしています。ただし、シェルスクリプトは複数のシグナルをトラップするため、スクリプト自体はSIGTERMで停止されず、systemdはSIGKILLを使用して90秒待機後にプロセスを停止します。私はそれを理解することができます:trap
子が終了した後にのみ実行してください。
systemctl stop
今、なぜ子供たちに転送されないのかを理解しようとしていますSIGTERM
。man systemd.kill
教えてくださいデバイスが停止すると、デバイス制御グループの残りのすべてのプロセスが終了します(サービスの場合:ExecStop =で設定されているように停止コマンドを実行した後)。。
私の問題の基本的な例は次のとおりです。システム単位のファイルを呼び出しますunitdemo
。
[Unit]
Description=test
After=graphical.target systemd-user-sessions.service
[Service]
User=ubuntu
WorkingDirectory=~
PAMName=login
UnsetEnvironment=TERM
StandardOutput=journal
ExecStart=/tmp/mainscript
Restart=always
[Install]
WantedBy=graphical.target
主なスクリプト:
#!/bin/bash
function trapme() {
echo SIGTERM sent to main script, trapped but exiting now...
exit 0
}
echo starting main script
trap trapme SIGTERM
echo now starting child script /tmp/childscript
/tmp/childscript
echo child script exited...
下付き文字もあります:
#!/bin/bash
function trapme() {
echo childscript has been killed by SIGTERM...
exit 0
}
trap trapme SIGTERM
while true; do sleep 1; done
公開はsystemctl stop unitdemo
90秒の待機時間後にのみ停止し、SIGTERM
サブスクリプトには送信されません。ログに「childscriptが終了しました...」というメッセージがありません。
編集する man systemd.exec
より多くの情報があります。以下のPAMName
項目があります。
Note that when this option is used for a unit it is very likely
(depending on PAM configuration) that the main unit process will be
migrated to its own session scope unit when it is activated. This
process will hence be associated with two units: the unit it was
originally started from (and for which PAMName= was configured),
and the session scope unit. Any child processes of that process
will however be associated with the session scope unit only.
これは子供が受信されない理由を説明しますSIGTERM
。これで質問はこのセッションを終了する方法です。つまり、私は今始まっています。提供するしかし、それは会議そして、サービスを停止してもセッションは停止しません。
ところで、次のように添え字を停止する方法を見つけました。
trap "kill \`cat $xkillerfile\`; ..... "
/tmp/childscript &
echo $! > $killerfile
wait
…しかし、気分が悪いです。基本プロセスが停止したら、セッションsystemd
でPIDを停止してセッションを終了する方法はありますか?それでは、どうすればいいですか?
答え1
この問題は、Systemd デバイスに次の設定がある場合に発生します。
KillMode=mixed
または
KillMode=process
質問に表示したコードにそのような項目が含まれていないため、これは奇妙です。デフォルトは
KillMode=control-group
ただし、この設定をこの[Service]
セクションに追加できます。このタスク(および明らかなタスクsystemctl daemon-reload
)を実行する前に、この設定のステータスを確認できます。
systemctl show unitdemo | grep -i KillMode