Bashの代わりにShによって実行されるシェルスクリプトを考えてみてください(変更することも、shebangを使用することも、無視します)。交換員は&
働くけどdisown $!
仕事しないよ、Shが文句言ってくれ」拒否:見つかりません」。
特定のShからバックグラウンドプロセスを分離する方法は?私の言うことは、Shで行うことはdisown
Bashで行うことと同じです。
答え1
まず、Bashコマンドが実行する作業を見てみましょうdisown
。 ~からバッシュマニュアル:
SIGHUP
対話型シェルは、終了する前にSIGHUP
実行中または停止したすべてのジョブを再送信します。停止したジョブを送信して受信したことをSIGCONT
確認しますSIGHUP
。シェルがSIGHUP
特定のジョブにシグナルを送信しないようにするには、disown組み込み関数(ジョブ制御の組み込みを参照)を使用して、ジョブテーブルから削除または受信しないようにマークする必要がありますSIGHUP
。 disown 組み込み関数disown -h
。
huponexit
シェルオプションが設定されている場合shopt
(Shoptの組み込みを参照)、SIGHUP
Bashはインタラクティブログインシェルの終了時にすべてのジョブにaを送信します。
これは、シェル自体がそれを受け取ると、SIGHUP
それをバックグラウンドジョブに渡すことを意味します。シェルが終了してアクティブでhuponexit
ない場合、端末を制御しないバックグラウンドプロセスはSIGHUP
端末を閉じません。
SIGHUP
したがって、問題がシェルラッパーで開始されたプロセスをブロックすることである場合は、次のようになります。
#!/bin/sh
my-command arg &
disown
その後、同様の機能は必要ありません。なぜなら、シェルmy-command
が終了する前にそれを取得しない限り、シェルはそれを受け取らないからです。SIGHUP
ただし、次のようにサブアイテムを起動した後もしばらく実行され続けるスクリプトでサブアイテムを実行しようとすると、まだ問題があります。
#!/bin/sh
sleep 55555 &
sleep 3333 # some long operation we don't care about
sleep 55555
上記のスクリプトは、スクリプトの制御端末が閉じるとコマンドを終了します。 Bourneシェルには、disown
Bash、Ksh、およびその他の一部のシェルに組み込まれている機能がないため、他のツールが必要です。そのツールはnohup(1)
。上記のスクリプトでは、サブプロセスの合計stdout
に興味がなく、次のことを避けるstderr
ために次のように変更できます。sleep
SIGHUP
#!/bin/sh
nohup sleep 55555 >/dev/null 2>&1 &
sleep 3333 # some long operation we don't care about
リダイレクトは、現在のディレクトリからファイルをインポートしないよう/dev/null
にすることです。nohup.out
リダイレクトがない場合、このファイルにはnohuppedプロセスの出力が含まれます。