2つの違いは何ですか
$ nohup foo
そして
$ foo &
そして
$ foo &
$ disown
ベストアンサー1
まず、リダイレクトなし(およびリダイレクトなし)の対話型シェル(ターミナルに接続)でプログラムを起動すると、&
何が起こるかを見てみましょう。先ほど入力したとしましょうfoo
。
- 実行中のプロセスが
foo
作成されました。 - プロセスはシェルから stdin、stdout、および stderr を継承します。だから同じ端末にも接続されています。
- シェルがを受信すると、プロセスにも送信されます(これは通常プロセスを終了します)
SIGHUP
。SIGHUP
- それ以外の場合、シェルはプロセスが終了または停止するまで待機(ブロック)します。
次に、プロセスをバックグラウンドに置くと、何が起こるかを見てみましょう。つまり、次のように入力してくださいfoo &
。
- 実行中のプロセスが
foo
作成されました。 - プロセスはシェルからstdout / stderrを継承します(それでも端末に書き込みます)。
- 原則として、プロセスはstdinも継承しますが、stdinから読み取ろうとするとすぐに停止します。
- これは、シェルが管理するバックグラウンドタスクのリストに含まれます。これは特に次のことを意味します。
- これはリストされており(ジョブ番号はどこにありますか?)を使用してアクセス
jobs
できます。%n
n
fg
を使用してフォアグラウンドタスクに変換できます&
。- シェルが1つを受け取ると、プロセスにも1つを送信します
SIGHUP
。SIGHUP
シェルとシェルに設定できるオプションに応じて、シェルが終了したらプロセスにもSIGHUP
送信します。
- これはリストされており(ジョブ番号はどこにありますか?)を使用してアクセス
ジョブがdisown
シェルのジョブリストから削除されたため、上記のすべての子は適用されなくなりました(SIGHUP
シェルから送信されたプロセスを含む)。しかし、参考にしてくださいまだターミナルに接続してターミナルが破壊され(xterm
またはによって生成されたptyのようなptyの場合に発生する可能性がありますssh
)、xtermを閉じるか、または制御プログラムが終了する場合SSH接続)、プログラムは標準入力から読み取るか、標準出力に書き込もうとするとすぐに失敗します。
一方、nohup
プロセスを端末から効果的に分離します。
- 標準入力を閉じます(プログラムはいいえフォアグラウンドで実行している場合でも、すべての入力を読み取ることができます。停止しませんが、エラーコードまたは
EOF
)が表示されます。 - 標準出力と標準エラーをファイルにリダイレクトするため、
nohup.out
端末が失敗しても標準出力に書き込んでプログラムが失敗しないため、プロセスで作成した内容はすべて失われません。 - これは、プロセスが
SIGHUP
(したがって名前)を受け取るのを防ぎます。
nohup
実際にもそうです。いいえシェルのジョブコントロールからプロセスを削除し、バックグラウンドに入れます(ただし、フォアグラウンドジョブはやや役に立たないため、通常はバックグラウンドnohup
に置くことを使用します&
)。たとえば、とは異なり、disown
シェルはnohup操作が完了したときに通知します(もちろん、シェルが以前にシャットダウンされていない場合を除く)。
結論として:
&
タスクをバックグラウンドに残します。つまり、入力を読み取ろうとしたときにジョブをブロックし、シェルがジョブが完了するのを待たないようにします。disown
シェルのジョブ制御からプロセスを削除しますが、端末には接続され続けます。 1つの結果は、シェルがそれを送信しないことですSIGHUP
。バックグラウンドジョブの実行中は入力できないため、これはバックグラウンドジョブにのみ適用されます。nohup
端末からプロセスを切断し、出力を端末にリダイレクトしてnohup.out
マスクしますSIGHUP
。効果の1つ(名前付き)は、プロセスが送信されたものを受信しないことですSIGHUP
。これはジョブ制御とは完全に独立しており、原則としてフォアグラウンドジョブにも使用できます(非常に有用ではありません)。