私はexec
これを次のように使用します:
#!/bin/bash
exec > >(tee /tmp/mylog.log) 2>&1
bash -c 'sleep 12312' &
コマンドの出力をログファイルに保存し、長期実行スクリプトを起動して、出力に対して何もせずに完全に切り離そうとします。
しかし、execを使用して出力をファイルにリダイレクトするスクリプトを実行すると、長期実行スクリプトとして実行され続けることがわかりました。たとえば、上記のスクリプトをファイルに保存して/tmp/start.sh
実行すると、まだ実行中ps aux
というメッセージが表示されます。/bin/bash /tmp/start.sh
しかし、exec行を削除すると、期待どおりに機能します。
それでは、exec stdoutリダイレクトを「分離」してスクリプトが終了するとすぐにスクリプトを終了させるにはどうすればよいですか?
答え1
継続的に実行されるbashプロセスは、元のtee
スクリプトではなく親プロセスです。プロセスIDを示すトレースを追加すると、それを確認できます。
#!/bin/bash
echo original=$$
exec > >(echo substitution=$BASHPID; tee /tmp/mylog.log) 2>&1
bash -c 'echo sleeper=$$; sleep 12312' &
これにより、追加のbashプロセスが表示されますsleep
。これらの bash プロセスを削除するには、exec
次のようにします。
#!/bin/bash
echo original=$$
exec > >(echo substitution=$BASHPID; exec tee /tmp/mylog.log) 2>&1
bash -c 'echo sleeper=$$; exec sleep 12312' &
私はbash 4.3でこの答えをテストしました。 bashの将来のバージョンは、kshのようなテールコールよりもスマートになる可能性があります。