
バックグラウンドで始まるコマンドを含むbashスクリプトを使用していますscript.sh
。cmd
#!/bin/bash
…
cmd &
…
ターミナルエミュレータを開いて実行すると、期待script.sh
どおりcmd
にバックグラウンドで正しく実行されます。つまり、script.sh
終了したにもかかわらず、cmd
PPID 1でバックグラウンドで実行され続けます。
ただし、古いターミナルエミュレータ(または実際のユースケースであるデスクトップセッションの先頭)で別のターミナルエミュレータ(xfce4-terminalと仮定)を開き、次のコマンドを実行するscript.sh
と
xfce4-terminal -H -x script.sh
cmd
これ以上正しく実行されません。終了しますscript.sh
。単にnohup
予防するだけでは十分ではありません。私はsleep
その後に命令を出す義務があります。それ以外の場合は、cmd
接続が切断される前の終了によって終了します。script.sh
cmd
バックグラウンドで正しく実行する唯一の方法は、最初のケースではなく、この場合に必要なのはなぜですかset -m
?script.sh
2つの実行script.sh
(したがってcmd
)の間に動作に違いがあるのはなぜですか?
最初のケースでは、ウォッチフェイスが次のようになります。いいえset -o
と入力すると、表示されるようにアクティブになりますscript.sh
。
答え1
実行する必要があるプロセスは間のシグナルによって終了し、cmd
ラッパーやその他の項目は実行される機会がなく、効果はありません。 (チェックを使用してもよい)SIGHUP
fork()
exec()
nohup
strace
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 &
と、SIGHUP
script.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
答え2
私はこれで遊んだ。私はそれを見つけることができませんでしたが、ここに私が見つけたものがあります。私はコマンドとしてスリープ3を使用します。
これら2つが機能します。ls
最終的な効果が何であるかわかりません。角かっことdoubleはnohup
子プロセスを形成します(それがうまくいく方法だと思いますnohup
)。なぜnohup
それ自体がうまくいかないのかわかりません。
#!/bin/bash
nohup nohup sleep 3 &
ls #no idea why I need this
そして
#!/bin/bash
(
nohup sleep 3 &
ls #no idea why I need this
)
/bin/true
交換作業ls
。外部コマンドを呼び出す必要があるようです。まだ理由がわからない。