web-dev-qa-db-ja.com

親が死亡した場合、子プロセスは引き続き実行されます

GUI(lightdm)を介して実行されるbashスクリプトがあります。

スクリプト中のある行で、次のようにします。

  1. Sudo service lightdm stop-GUIを停止します
  2. 例を使用して、TTY(tty1tty7など)を引き継ぎます。exec </dev/tty7 >/dev/tty7 2>&1
    agettyがTTYを制御している場合、簡単にSIGSTOPを送信できます)。
    tty7が推奨されます。これは、lightdmをシャットダウンしている間、それが使用可能になるためです。

問題は、bashスクリプトがlightdmサービスの子であるということです。
したがって、Sudo service lightdm stopの実行中に、スクリプト/プロセスを終了しようとします。

Nohupを使用する必要があることがわかりましたが、既に実行中のスクリプト/プロセスをSIGHUPの影響を受けないようにすることを好みます。
私は 提案disownbgについて見てきましたが、スクリプトファイルがインタラクティブモードではないため、bgできません。また、set -mを使用しても、とにかく押す必要があるため、役に立ちません。 CTRL+Z プロセスを一時停止するため(SIGTSTPを送信すると一時停止しますが、ファイルは実行を継続しません...)。

これを解決するための信頼性が高く堅牢なアプローチは何ですか?
Ubuntuの使用。


更新8Oct 21:35 UTC- @ countermodeへの返信:

私は試した:

trap '' HUP
service lightdm stop

また試した:

trap '' SIGHUP
service lightdm stop

しかし、それは失敗しました。 service lightdm stop行の後にデータをファイルに書き込んだため、失敗したことはわかっています。これらのファイルの変更時間は(1日前)古すぎるため、機能しません。

私は、以下を使用して、欠落していると思ったすべての信号をキャッチしようとしました。

trap_with_arg() {
    func="$1" ; shift
    for sig ; do
        trap "trap_handler $sig" "$sig"
    done
}
trap_handler() {
    echo -e " \n Caught signal $1 \n" >>/path_to_some_folder/_signals.txt
}
echo "" >/path_to_some_folder/_signals.txt
signals_list=""
for i in {1..64} ; do
    signals_list+="$(kill -l $i) "
done
trap_with_arg trap_handler 0 $signals_list

service lightdm stop

ここでアドバイスされているように
キャッチされたすべての信号は(左が最初でした):HUPCONT0

だから私はしようとしました:

trap '' 0 HUP CONT
service lightdm stop

しかし、それも失敗しました...


更新9Oct 08:46 UTC:

実際、@ countermodeの答えはうまく機能します。
コードに小さな間違いがあったので、うまくいかないと思いました。

3
Dor

シェルスクリプトは、trapキーワードを使用して独自のシグナルハンドラーを設定できます。シナリオでは、SIGHUPを無視したいので、ldmセッションを終了する前にどこかに電話をかけます

trap '' SIGHUP

どこ ''(空の文字列)は、SIGHUPを無視することを示します(それ以外の場合は、ここでシグナル処理コードを指定します)。

2
countermode