web-dev-qa-db-ja.com

`> my.log 2>&1&`によってジョブがログアウトを維持するのはなぜですか?

私が使う

myscript > my.log 2>&1 &

スクリプトを実行してその出力を収集するには、ログアウトしてもスクリプトは引き続き実行されます。 myscript &で開始することになっていた-ログアウト後すぐに終了します。

しかし、それは奇妙な効果です。> my.log 2>&1 &が行うことは、stderrをstdoutにリダイレクトすることだけです...

> my.log 2>&1 &によってジョブがログアウトを維持するのはなぜですか?

6
Adobe

通常、バックグラウンドに何かを置くと、親シェルが終了した後も実行を継続します。実際、次のようなテストケースを作成できます。

/bin/sh -c 'while true; do echo hi; sleep 5; done' &

次にシェルを終了し、psを使用すると、シェルを強制終了するまで、シェルが永久に実行されていることがわかります。

出力をリダイレクトする場合とリダイレクトしない場合の違いが1つあります。出力をリダイレクトせずにシェルを終了すると、stdout/stderrファイル記述子が閉じられ、次にそれらに書き込もうとしたときに書き込み操作が失敗します。スクリプトがそれをチェックしている場合、または-e(エラー時に終了)オプションを設定して実行している場合、スクリプトは停止します。上記の動作をこのバージョンと比較してください。

/bin/sh -c 'while true; do echo hi || exit 1; sleep 5; done' &

または

/bin/sh -ec 'while true; do echo hi; sleep 5; done' &

これを実行したままにして、シェルを終了し、psを使用すると、echoを実行しようとすると失敗し、終了することがわかります。

出力をファイルにリダイレクトする場合、明らかに書き込みは失敗せず、スクリプトは引き続き実行されます。

8
MadScientist

> my.log 2>&1はそれとは何の関係もありません。代わりに、最後の&には、プロセスをバックグラウンドで実行する役割があります。コマンドを入力した後に返される行には、process id(pid。)の番号が表示されます。必要に応じて、プロセスを終了するために、後でkillコマンドを使用してこの番号を使用できます。

とはいえ、あなたの場合、私はすべてをscreenで実行します。を使用して画面を開始できます

screen -S <name>

その後、コマンドを実行します。画面から切り離す(最初の端末に戻る)には、CTRLを押す必要があり、順番にADを押す必要があります。次のように入力した画面を再接続します。

screen -r <name>

このように(画面でタスクを実行する)、ユーザーがログアウト/切断しても実行されます。最良の部分は、reattachコマンドで結果を確認できることです。

1
Silviu

不滅のプロセスをデーモンと比較してみましょう。デーモンはユーザーや端末と相互作用せず、initが死ぬと死にます(意図的に停止されない限り)。

nohupを使用し、/ dev/nullにリダイレクトすることで、std.outとstd.errを「デーモンを作成」できます。

Nohup ping google.com 2>/dev/null>/dev/null-これIS IMMORTAL。

0
fromnaboo