私が使う
myscript > my.log 2>&1 &
スクリプトを実行してその出力を収集するには、ログアウトしてもスクリプトは引き続き実行されます。 myscript &
で開始することになっていた-ログアウト後すぐに終了します。
しかし、それは奇妙な効果です。> my.log 2>&1 &
が行うことは、stderrをstdoutにリダイレクトすることだけです...
> my.log 2>&1 &
によってジョブがログアウトを維持するのはなぜですか?
通常、バックグラウンドに何かを置くと、親シェルが終了した後も実行を継続します。実際、次のようなテストケースを作成できます。
/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
を実行しようとすると失敗し、終了することがわかります。
出力をファイルにリダイレクトする場合、明らかに書き込みは失敗せず、スクリプトは引き続き実行されます。
> my.log 2>&1
はそれとは何の関係もありません。代わりに、最後の&
には、プロセスをバックグラウンドで実行する役割があります。コマンドを入力した後に返される行には、process id
(pid。)の番号が表示されます。必要に応じて、プロセスを終了するために、後でkill
コマンドを使用してこの番号を使用できます。
とはいえ、あなたの場合、私はすべてをscreen
で実行します。を使用して画面を開始できます
screen -S <name>
その後、コマンドを実行します。画面から切り離す(最初の端末に戻る)には、CTRL
を押す必要があり、順番にA
とD
を押す必要があります。次のように入力した画面を再接続します。
screen -r <name>
このように(画面でタスクを実行する)、ユーザーがログアウト/切断しても実行されます。最良の部分は、reattachコマンドで結果を確認できることです。
不滅のプロセスをデーモンと比較してみましょう。デーモンはユーザーや端末と相互作用せず、initが死ぬと死にます(意図的に停止されない限り)。
nohupを使用し、/ dev/nullにリダイレクトすることで、std.outとstd.errを「デーモンを作成」できます。
Nohup ping google.com 2>/dev/null>/dev/null-これIS IMMORTAL。