バックグラウンドで開始する前にプロセスが終了しました。

バックグラウンドで開始する前にプロセスが終了しました。

バックグラウンドで始まるコマンドを含むbashスクリプトを使用していますscript.shcmd

#!/bin/bash
cmd &

ターミナルエミュレータを開いて実行すると、期待script.shどおりcmdにバックグラウンドで正しく実行されます。つまり、script.sh終了したにもかかわらず、cmdPPID 1でバックグラウンドで実行され続けます。

ただし、古いターミナルエミュレータ(または実際のユースケースであるデスクトップセッションの先頭)で別のターミナルエミュレータ(xfce4-terminalと仮定)を開き、次のコマンドを実行するscript.sh

xfce4-terminal -H -x script.sh

cmdこれ以上正しく実行されません。終了しますscript.sh。単にnohup予防するだけでは十分ではありません。私はsleepその後に命令を出す義務があります。それ以外の場合は、cmd接続が切断される前の終了によって終了します。script.sh

cmdバックグラウンドで正しく実行する唯一の方法は、最初のケースではなく、この場合に必要なのはなぜですかset -mscript.sh2つの実行script.sh(したがってcmd)の間に動作に違いがあるのはなぜですか?

最初のケースでは、ウォッチフェイスが次のようになります。いいえset -oと入力すると、表示されるようにアクティブになりますscript.sh

ベストアンサー1

実行する必要があるプロセスは間のシグナルによって終了し、cmdラッパーやその他の項目は実行される機会がなく、効果はありません。 (チェックを使用してもよい)SIGHUPfork()exec()nohupstrace

nohupバックグラウンドコマンドを実行する前に、親シェルでSIGHUP(ignore)に設定する必要があります。SIG_IGNシグナルハンドラが「ignore」または「default」に設定されている場合、設定は転送され継承されfork()ますexec()。例:

#! /bin/sh
trap '' HUP    # ignore SIGHUP
xclock &
trap - HUP     # back to default

または:

#! /bin/sh
(trap '' HUP; xclock &)

xfce4-terminal -H -x script.sh次のようにこのスクリプトを実行するxclock &と、SIGHUPscript.sh

セッションリーダー(あなたの場合は制御端末を「所有」するプロセスscript.sh)が終了すると、カーネルはSIGHUPそのリーダーで実行されます。展望プロセスグループですが、ジョブ制御が有効になり、set -m次に始まるコマンドがアクティブになります。&背景プロセスグループを介して信号をエクスポートしませんSIGHUP

ジョブ制御が有効になっていない場合(非対話型スクリプトのデフォルト&展望プロセスグループ、「バックグラウンド」モードは偽造されます。リダイレクト彼らの意見を/dev/null受け入れる無視する SIGINTそしてSIGQUIT

SIGHUPプロセスは一時的にフォアグラウンドジョブとして実行されましたが、そのプロセスグループ(死んだ親プロセスから継承されます)がターミナルのフォアグラウンドプロセスではなくなったため、終了したスクリプトからこのようにシグナルを受け取ります。

追加の指示:

xtermと(そしておそらく他のvteベースの端末)xfce4-terminalの間に「保留モード」に違いがあるようです。前者はptyのマスター側を開いたままにしますが、後者はプログラムが実行または終了した後にptyを引き裂き、-eスレーブ-x側へのすべての書き込みが失敗して表示されるようにしますEIO。フォアグラウンドプロセスグループでプロセスが実行され続けている間は、xtermメッセージも無視されます(つまり閉じません)。WM_DELETE_WINDOW

おすすめ記事