nohupとdisownの両方がシェルを終了した後にプログラムを実行することを許可できますか?

nohupとdisownの両方がシェルを終了した後にプログラムを実行することを許可できますか?

私はnohupUbuntuを見つけていますdisownbash

私は持っていますwhile.py

import time
while True:
    print(1)
    time.sleep(1)

まず、sshを使用してUbuntuサーバーに接続し、と入力してターミナルに入り、出てnohup python3 while.py &行きexitました。サーバーに再接続してを入力すると、ps aux | grep pythonプロセスが実行されていることを明確に表示できます。その後、プロセスを終了します。

第二に、に入りましたpython3 while.py & disown。プログラムは1シェルから印刷を開始します。その後、シェルを終了してサーバーに再接続します。ただし、 を入力すると、ps aux | grep pythonプロセスが実行されていることがわかりません。

拒否しても端末を閉じた後にプロセスが終了するのを防ぐことはできないようです。関連問題を検索してみました。セルチクdisownシェルがSIGHUPを送信していないことを確認し、プロセスが送信したnohupSIGHUPを受信して​​いないことを確認することに言及しました。この回答端末が終了したときに、すべてのプロセスにSIGHUP、SIGCONT、SIGCHIDを送信すると言いました。だからターミナルを閉じた後、nohupとdisownが異なる動作をする理由は何ですか?

英語は私の母国語ではありません。文法的な誤りがあっても許してください。助けてくれてありがとう。

答え1

もともとUnixハードウェア環境では、「ターミナル」はシリアルポートに接続されたハードウェアでした。これは、実際の端末、電話回線モデム、または同様のものです。

リモートモデムを使用してモデムを呼び出して接続すると、システムにログインします。切断すると(「電話を切る」)、システムはシリアルポートに接続されているすべてのデバイスにHUPを送信します。その後、システムはman -s 7 signalシリアルポートに接続されている各プロセスにHUP信号(参考資料を参照)を送信して信号を消去し、次のユーザーがポートを使用できるようにします。物理端末を終了すると、途切れもシミュレートされます。

シリアルポートはまだ存在しますが、ほとんどの「ターミナル」は仮想でソフトウェアで実装され、擬似端末(pty)インターフェイスを介して接続されます。しかし、これはまだシリアルポートとほぼ同じです。擬似端末には2つのインターフェースがあります。 1つはターミナルソフトウェア接続のための基本インターフェースであり、もう1つは外部シリアルポートのソフトウェア側と同じ機能を持つクライアントです。

メインptyが閉じる(ウィンドウを閉じたり、sshを切断したりするなど)、他のいくつかの操作が発生すると、モデムの切断と同じイベントがトリガーされ、端末に接続されているすべてのプロセスにHUP信号が送信されます。

このnohupコマンドは、プロセスがHUP信号を受信するのを防ぎ、プロセスが直接終了しないようにします。ただし、標準入力と標準出力が端子に接続されている可能性があります。マスター pty が閉じた後、stdin と stdout は効果的に /dev/null に置き換えられます。これにより、読み取りを試みるときにプロセスがstdinからEOFを受信して​​まだ終了する可能性があります。

シェルにバックグラウンドジョブがあり、シェルを終了すると、通常はHUP信号を使用して自分でクリーンアップするジョブを終了しようとします。このdisownコマンドは、ジョブ制御リスト内のジョブを削除するようにシェルに指示します。これは、端末からワークプロセスの接続を解除せず、端末は依然としてそのプロセスを削除しようとする可能性があります。

答え2

問題の原因を発見しました。この回答話す

端末の場合破壊される(これはxtermまたはsshによって生成されたものと同じptyであり、xtermを閉じるかSSH接続を終了して制御プログラムが終了した場合に発生する可能性があります。)失敗する一度試したら標準入力から読むまたは標準出力への書き込み

Disownは、ターミナルがシャットダウンした後に切断またはstdoutdisownしませんstderr。私のプログラムはprint(1)書き込みを試みstdout、プログラムがクラッシュします。

stdoutこの問題を解決するには、リダイレクトして転送するだけstderrです。python3 while.py >/dev/null 2>&1 & disown

答え3

disown はシェルのジョブ制御からプロセスを削除し、プロセスは依然として端末セッションに接続するため、端末を終了するとプロセスは終了します。

関連情報