nohup、disown、および&の違い


579

の違いは何ですか

$ nohup foo

そして

$ foo &

そして

$ foo & 
$ disown

50
待ってください、PIDを指定せずに否認できますか?すばらしいです!
ripper234

34
またfoo &!、最初からそれを否認することと同等であるべきものもあります。
user4514

26
Bashは&!をサポートしていません。
ジョナスコングスランド

20
foo & disownすぐに否認する。
ctrl-alt-delor

9
私はの言及を見てみたいsetsid、とどのようにそれが関連disownしてnohup
YoungFrog

回答:


558

最初に、プログラムが(端末に接続された)対話型シェルから&(リダイレクトなしで)起動された場合に何が起こるかを見てみましょう。だからあなたがタイプしたと仮定しましょうfoo

  • 実行中のプロセスfooが作成されます。
  • プロセスは、シェルからstdin、stdout、およびstderrを継承します。そのため、同じ端末にも接続されます。
  • シェルがを受信すると、プロセスにSIGHUPもを送信SIGHUPします(通常、プロセスは終了します)。
  • それ以外の場合、シェルはプロセスが終了するまで待機します(ブロックされます)。

ここで、プロセスをバックグラウンドに置いた場合、つまり次のように入力した場合にどうなるか見てみましょうfoo &

  • 実行中のプロセスfooが作成されます。
  • プロセスは、シェルからstdout / stderrを継承します(したがって、まだ端末に書き込みます)。
  • プロセスは原則としてstdinも継承しますが、stdinから読み取ろうとするとすぐに停止します。
  • これは、シェルが管理するバックグラウンドジョブのリストに追加されます。つまり、特に次のことを意味します。
    • にリストされてjobsおり、%n(を使用してアクセスできます)を使用してアクセスできますn
    • を使用してフォアグラウンドジョブに変換できます。fgこの場合、使用&しないかのように続行します(標準入力から読み取ろうとして停止した場合は、ターミナルからの読み取りに進むことができます)。
    • シェルがを受信した場合、プロセスにSIGHUPもを送信SIGHUPします。シェルおよび場合によってはシェルに設定されたオプションに応じて、シェルを終了するときSIGHUPにプロセスにaも送信します。

これでdisown、シェルのジョブリストからジョブが削除されるため、上記のすべてのサブポイントは適用されなくなります(SIGHUPシェルから送信されるプロセスを含む)。ただし、まだ端末に接続されていることに注意してください。そのため、端末が破壊されたxterm場合(またはによって作成されたもののようなptyの場合に発生する可能性がありssh、xtermを閉じるかSSH接続を終了することで制御プログラムが終了します) 、プログラムは標準入力からの読み取りまたは標準出力への書き込みを試みるとすぐに失敗します。

nohup一方、何を行うかは、プロセスをターミナルから効果的に分離することです。

  • 標準入力を閉じます(フォアグラウンドで実行されていても、プログラムは入力を読み取ることができません。停止されませんが、エラーコードまたはを受け取りますEOF)。
  • それは標準出力と標準エラーをファイルにリダイレクトするnohup.outので、ターミナルが失敗してもプログラムは標準出力への書き込みに失敗しないので、プロセスの書き込みは失われません。
  • プロセスがSIGHUP(したがって名前を)受信するのを防ぎます。

nohupではないシェルのジョブ制御からプロセスを削除しても、バックグラウンドでそれを入れていません(ただし、フォアグラウンドので、nohupジョブは多かれ少なかれ役に立たない、あなたは一般的に使用してバックグラウンドにそれを置くところ&)。たとえば、とは異なりdisown、シェルはnohupジョブがいつ完了したかを通知します(もちろん、シェルが前に終了しない限り)。

要約すると:

  • & ジョブをバックグラウンドに配置します。つまり、入力を読み取ろうとするとブロックし、シェルは完了を待機しません。
  • disownシェルのジョブ制御からプロセスを削除しますが、端末に接続したままにします。結果の1つは、シェルがを送信しないことSIGHUPです。フォアグラウンドジョブの実行中は入力できないため、明らかにバックグラウンドジョブにのみ適用できます。
  • nohupプロセスを端末から切断し、その出力をにリダイレクトしnohup.outて、から保護しSIGHUPます。効果の1つ(ネーミングの1つ)は、プロセスが送信されSIGHUPたものを受け取らないことです。これはジョブ制御から完全に独立しており、原則としてフォアグラウンドジョブにも使用できます(ただし、あまり有用ではありません)。

8
+1ありがとう。disown、nohup、および&を一緒に使用するとどうなりますか?
ティム

15
3つすべてを一緒に使用すると、プロセスはバックグラウンドで実行され、シェルのジョブ制御から削除され、ターミナルから事実上切断されます。
celtschk


1
違いは何だdisown %1とはdisown -h %1?2番目は、端末が終了するまで通常のジョブとして保持されます(ただし、HUPシグナルは無視します)。
schemacs

4
(foo&)サブシェルを含める価値があるかもしれませ
ん-jiggunjer

169

を使用する&と、プログラムがバックグラウンドで実行されるため、プログラムが終了するまでブロックするのではなく、新しいシェルプロンプトが表示されます。nohupそしてdisown、ほとんど無関係です。これらはSIGHUP(ハングアップ)シグナルを抑制し、制御端末が閉じられたときにプログラムが自動的に強制終了されないようにします。nohupジョブが最初に開始されたときにこれを行います。nohup開始時にジョブを実行しない場合disown、実行中のジョブを変更するために使用できます。引数なしで、それは現在のジョブを変更します。


10
nohupとdisownの小さな違い:disownコマンドはジョブリストからそれを削除します。nohupはしません。
ショーンJ.ゴフ

191
nohupそして、disownの両方を抑制すると言うことができるSIGHUPが、異なる方法で。nohupプログラムが最初にシグナルを無視するようにします(プログラムはこれを変更する場合があります)。nohupまたSIGHUP、端末が閉じられたときにカーネルによって送信されないように、制御端末を持たないようにプログラムを調整しようとします。disown純粋にシェルの内部です。SIGHUP終了時にシェルは送信しません。
ジル

27
@Gilles、あなたのコメントはそれ自身の答えの価値があります。
レスマナ

5
disownジョブリストからジョブを削除することに関する@ ShawnJ.Goffのコメントの明確化。オプションを指定しない場合、ジョブリストから削除されます。ただし-hオプションを指定した場合、各jobspecはテーブルから削除されません。代わりに、SIGHUPシェルがを受信した場合にジョブに送信されないようにしSIGHUPます。
tacotuesday

4
ちょうど使用して、明確にするために&あなたの端末を与えるものではありません、それは切り離しstdinプロセスから、バックグラウンドで実行するようになりますが、両方stdoutstderr、まだ現在のttyに装着されています。これは、さまざまなプログラムからテキストが混ざり合っている可能性があることを意味します。これを行うgimp &と、他の何かにそのttyを使用しようとしているときに多くのGTK +エラーが発生します。
フランク14年

8

これは、終了しないコマンド(例tail)に続いて、バックグラウンドでsofficeを実行しようとした私の経験です。この例では、を使用しますsleep 100

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

私が見るとsoffice ログを押して/ Ctrl- Cとsofficeの停止を

nohup ..&

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

私は見ていないとsofficeのログを押して/ Ctrl- Cとsofficeの停止を

&disown

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

私が見るとsoffice ログを押して/ Ctrl- Cとsofficeの停止を

setsid ..&

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

私が見るとsoffice ログを押して/ Ctrl- Cとsofficeが止まりません

スペースを節約するために:
nohup setsid ..:ログが表示されません/とsofficeが上停止しないCtrl-C
nohup& disown末尾に:ログを表示しません/ とsofficeは上停止しますCtrl-C


2
setsidに言及し、その特定の状況で何が起こるかを示す努力に感謝しますが、より徹底的な答えをご覧ください。特に、各ソリューションの違いと類似点は、目に見える(シェルまたはターミナルを閉じると何が起こるか、出力はどこに行くかなど)と見えない(フードの下で物事がどのように行われるか、およびその意味)。受け入れられた答えは、そのための良いベースです。
YoungFrog

1
@YoungFrogこれに同意します!
マリノス

私にとって、nohup ⟨command⟩ & disown作成されたプロセスはで停止しませんCtrl+C
k.stm

@ k.stm試しましたsofficeか?sofficeコマンドは何か違うようです。そこで、ここでルールの例外として追加することを検討しました。例えば:を使用している場合nohup .. &Ctrl-c通常押すとコマンドは停止しませんが、停止sofficeします。誰かがこれを踏んで、なぜこれがsofficeで起こるのかを説明するまで待ちます:)
Marinos An

@MarinosAnはい、できました。私は走っnohup soffice &て押したCtrl+C。予想通り、何も起こりませんでした。
k.stm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.