「&」を使用しています。プロセスがバックグラウンドで実行されないのはなぜですか?

「&」を使用しています。プロセスがバックグラウンドで実行されないのはなぜですか?

&バックグラウンドでプロセスを実行するコマンドをリンクできることがわかります。

SSHを介してUbuntu 12.04システムに接続し、$python program.py &-を使用してPythonプログラムを実行していますが、ターミナルウィンドウを閉じるとターミナルを閉じると、実行中のプロセスが終了するというメッセージが表示されます。

なぜこれですか? &記号を使用してバックグラウンドでプロセスを実行しています。 SSHを介して接続されているかどうかに関係なく、どのように機能させますか?

答え1

ターミナルウィンドウを閉じると、ターミナルエミュレータは実行中のプロセス(シェルなど)にSIGHUPを送信します。その後、シェルはそのSIGHUPを実行中のすべての項目に渡します。ローカルシステムではsshです。その後、sshはSIGHUPを実行中のリモートシェルに渡します。したがって、リモートシェルはすべてのプロセス(デーモン)にSIGHUPを送信します。

この問題を解決する方法は2つあります。

  1. シェルからバックグラウンドプログラムの接続を解除します。
    1. disownプロセスをバックグラウンドに配置したら、このコマンドを使用します。これにより、シェルがこれを忘れてしまいます。
    2. コマンドの前にnohup()を追加しますnohup $python program.py &。これは同じことを行いますが、中間プロセスを使用します。デフォルトでは、SIGHUP信号を無視してから設定を継承するプログラムを分岐して実行し、終了します。フォークされるため、起動されるプログラムはシェルのサブルーチンではなく、シェルはそれを認識しません。 SIGHUP用のシグナルハンドラを取り付けない限り、無視されたままになります。
  2. ターミナルウィンドウを閉じる代わりにlogout(またはCtrl+)を使用してください。dを使用すると、logoutこれはSIGHUPではないため、シェルは子にSIGHUPを送信しません。

また、プログラムがSTDOUTまたはSTDERRを介して端末に書き込まないようにする必要があります。端末が終了すると、両方とももはや存在しないからです。そのようにリダイレクトしないと、/dev/nullプログラムは実行を続けますが、書き込みを試みるとSIGPIPEを受け取り、SIGPIPEのデフォルトの動作はプロセスを終了することです。

答え2

プロセスは端末のバックグラウンドで実行されますが、stdout(and stderr)の出力は依然として端末に送信されます。これを停止するには、両方の出力をリダイレクトする> /dev/null 2>&1前に追加してください。また、追加すると、端末を閉じた後もプロセスが終了しないことが確認されます。&/dev/nulldisown

COMMAND > /dev/null 2>&1 & disown

あなたの場合は次のとおりです。

python program.py > /dev/null 2>&1 & disown

答え3

演算子は、直列に実行するコマンドを分離する&のと同じように、並列に実行するコマンドを分離します;。両方のコマンドはまだシェルプロセスの子プロセスとして実行

したがって、これらのサブキーを起動したシェルを閉じると、そのサブキーも閉じられます。

あなたが望むもの悪魔、これは親プロセスで完全な分離を必要とするので、はるかに難しいです。シェルには通常これを行う簡単な方法はありません。

答え4

アンパサンド()で終わるコマンドの後に、コマンドプロンプト&で次のコマンドを実行します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

関連情報