web-dev-qa-db-ja.com

Nohup、disown、&の違い

違いは何ですか

$ Nohup foo

そして

$ foo &

そして

$ foo & 
$ disown
600
lesmana

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

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

次に、プロセスをバックグラウンドで実行した場合、つまりfoo &と入力するとどうなるかを見てみましょう。

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

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

一方、Nohupが行うことは、プロセスを端末から効果的に分離することです。

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

Nohupはシェルのジョブ制御からプロセスを削除しないだけでなく、バ​​ックグラウンドにも置かないことに注意してください(ただし、フォアグラウンドNohupジョブはまたはあまり役に立たない場合は、通常、&を使用してバックグラウンドに配置します。たとえば、disownとは異なり、シェルはNohupジョブが完了したときに通知します(もちろん、シェルが以前に終了している場合を除きます)。

要約すると:

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

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

174
Michael Mrozek

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

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

I see soffice logs/Ctrl-C soffice stop

Nohup ..&

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

I 表示されない soffice logs /を押す Ctrl-C 事務所停止

捨てる

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

I see soffice logs/Ctrl-C soffice stop

setsid ..&

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

I see soffice logs /を押す Ctrl-C soffice 停止しません

スペースを節約するには:
Nohup setsid ..:ログを表示しない/ soffice DOES NOT STOP on Ctrl-C
Nohup with & disown with the end:does not show logs/soffice stop on Ctrl-C

9
Marinos An