&
バックグラウンドでプロセスを実行するコマンドに追加できることを知っています。
Ubuntu 12.04ボックスにSSHで接続してpythonプログラムを実行しています$python program.py &
が、ターミナルウィンドウを閉じようとすると、ターミナルを閉じると実行中のプロセスが強制終了されるというメッセージが表示されます。
どうしてこれなの?アンパサンドを使用して、バックグラウンドでプロセスを実行しています。SSHを使用しているかどうかに関係なく、どうすれば実行できますか?
&
バックグラウンドでプロセスを実行するコマンドに追加できることを知っています。
Ubuntu 12.04ボックスにSSHで接続してpythonプログラムを実行しています$python program.py &
が、ターミナルウィンドウを閉じようとすると、ターミナルを閉じると実行中のプロセスが強制終了されるというメッセージが表示されます。
どうしてこれなの?アンパサンドを使用して、バックグラウンドでプロセスを実行しています。SSHを使用しているかどうかに関係なく、どうすれば実行できますか?
回答:
ターミナルウィンドウを閉じると、ターミナルエミュレータは実行中のプロセスであるシェルにSIGHUPを送信します。シェルは、そのSIGHUPを実行中のすべてに転送します。ローカルシステムでは、これはsshです。sshは、SIGHUPを実行中のリモートシェルに転送します。したがって、リモートシェルは、バックグラウンドプログラムであるすべてのプロセスにSIGHUPを送信します。
これには2つの方法があります。
disown
プロセスをバックグラウンドにした後にコマンドを使用します。これにより、シェルはそれを忘れます。nohup
(nohup $python program.py &
)を付けます。これは同じことを達成しますが、中間プロセスを使用します。基本的には、SIGHUPシグナルを無視し、設定を継承するプログラムを分岐して実行し、終了します。分岐しているため、起動されるプログラムはシェルの子ではなく、シェルはそれを認識しません。また、SIGHUPのシグナルハンドラーをインストールしない限り、無視アクションを保持します。logout
ターミナルウィンドウを閉じる代わりに使用します。を使用する場合logout
、これはSIGHUPではないため、シェルはその子にSIGHUPを送信しません。さらに、プログラムがSTDOUTまたはSTDERRを介して端末に書き込まないようにする必要があります。端末が終了すると、これらの両方が存在しなくなります。それらをのようなものにリダイレクトしない場合/dev/null
、プログラムは引き続き実行されますが、それらに書き込もうとするとSIGPIPEが取得され、SIGPIPEのデフォルトアクションはプロセスを強制終了します)。
ssh
死ぬと接続がドロップし、接続をドロップするとsshd
もう一方の端が死にます。リモートシェルが実行される疑似端末のマスター側を制御するそのsshdは、死んだときにハングアップ(実際の端末でプラグを抜くようなものです)であるため、システムはリモートシェルにSIGHUPを送信します。
nohup
含むnohup.out
ファイルが生成されることに注意してください。この方法でアプリを起動するためにnohupを使用するたびに(または出力をにリダイレクトする必要があるたびに)そのファイルを削除するのは面倒です/dev/null
。
nohup python program.py &
使用setsid python program.py
することをお勧めします。これにより、プログラムはすぐに無視されます。
アンパサンド(&
)で終わるコマンドの後、コマンドプロンプトで次のコマンドを実行しますbg
。
bash> python program.py &
bash> bg
これにより、「&」コマンドがバックグラウンドに配置されます
bash> jobs
これにより、バックグラウンドで実行されているジョブが一覧表示されます
bash> fg 1
これにより、ジョブ#1が前面に表示されます。
別の方法(ログアウトできるようにするため)
bash> at now
bash> /full/path/python /full/path/program.py
bash> ^d `(# That is, Control-D, to run the command, Control-C to cancel)`
at
^ d(Control-D)を
参照する前に、コマンドに複数の行を送信できますman at
。