web-dev-qa-db-ja.com

既に「&」を使用してフォークしている場合、「Nohup」はいつ必要ですか?

まず、この質問は関連していますが、この非常に素晴らしい質問とは明らかに異なります。

Nohup、disown、&の違い

何かを理解したいのですが、「&」を実行すると、正しく分岐しますか?

「Nohup ...&」を実行するのは便利ですか、それとも単に&十分ですか?

「&」を使用していても「Nohup」を使用したいというケースを誰かが示す可能性はありますか?

30
Cedric Martin

まず、コマンドを実行するたびに、&を使用して実行するかどうかに関係なく、シェルは新しいプロセスをフォークします。 &は、バックグラウンドで実行していることを意味します。

これはあまり正確ではないことに注意してください。 cdなどの一部のコマンドはシェル関数であり、通常は新しいプロセスをforkしません。 type cmdは通常、cmdが外部コマンドであるかシェル関数であるかを通知します。 type typeは、type自体がシェル関数であることを示します。

Nohupは何か違うものです。新しいプロセスにSIGHUPを無視するように指示します。これは、親シェルが閉じたときにカーネルによって送信される信号です。

質問に答えるには、次のようにします。

  1. run emacs &(デフォルトでは、別のXウィンドウで実行する必要があります)
  2. 親シェルでexitを実行します。

バックグラウンドで実行されているにもかかわらず、emacsウィンドウが強制終了されていることがわかります。これはデフォルトの動作であり、Nohupはそれを変更するために正確に使用されます。

バックグラウンドでジョブを実行する(&またはbgを使用すると、他のシェルにも他の構文があると思います)はシェル機能であり、最新のシステムのマルチタスク機能に由来します。起動するすべてのプログラムに対して新しいShellインスタンスをフォークする代わりに、最新のシェル(bashzshksh、...)は、プログラムのリスト(またはjobs)。 foregroundにあるのは一度に1つだけです。つまり、シェルフォーカスを取得します。フォアグラウンドで実行されているプロセスとバックグラウンドで実行されているプロセス(主なプロセスはstdin/stdoutへのアクセス)の違いについて誰かがもっと詳しく説明できたらと思います。

いずれの場合でも、これは子プロセスがSIGHUPに反応する方法には影響しません。 Nohupはします。

37
rahmu

Nohup ... &を行うことは便利ですか?はい。 &を使用して「バックグラウンドで」プロセスを開始しただけの場合、その新しいプロセスは元のシェルの「プロセスグループ」のメンバーシップを保持しています。そのシェルまたはプロセスグループが特定のシグナル(たとえば、SIGHUP)を受け取った場合、デフォルトで終了します。つまり、xterm、rxvt、またはその他のウィンドウターミナルエミュレーターによって起動されたシェルから&を使用してプロセスを実行した場合、ウィンドウを閉じると、バックグラウンドプロセスがSIGHUPを取得します。何気なく書いたコードはSIGHUPを処理しないため、終了します。

Nohup ... &を実行すると、NohupコマンドはSIGHUPを無視するように設定し、コマンドを実行します。新しく実行されたコマンドは、コマンドがシグナル処理自体を行わない限り、Nohupが設定したシグナルマスクを保持します。 xtermまたはrxvtなどを閉じると、カーネルはコマンドのプロセスにSIGHUPを配信しますが、無視されます。それは走り続けます。

コマンドでNohupを実行すると、xtermを閉じた後、またはログオフした後もコマンドを実行し続けることができます。

18
Bruce Ediger

ここで言及していないことの1つは、「端末出口でのHUPの送信」イベントは構成可能です-発生する場合と発生しない場合があります。これは、Nohupがどのように機能しているかについての一部の人々の認識を混乱させるかもしれません。端末出口でのHUPの送信が無効になっている場合、Nohupは不要であるという結論に達します。端末出口でのHUPの送信は、bashのシェルオプションです。

試す

shopt | grep huponexit

これにより、HUPが端末出口で送信されているかどうかがわかります。その場合、Nohupを使用する必要があります。そうでない場合は、しません。

0
Matt Warren