すべての出力を1つのファイルにリダイレクトし、さらにstderrを別のファイルにリダイレクトする必要があります。これは簡単にできますか?
この例の目的のための私のコマンドが次のとおりであると仮定しましょう:
php /tmp/doWork.php
以下を使用して、個別のファイルに出力を取得できます。
php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file
this に基づいて、私は試みました:
php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file
しかし、これはstdoutとstderrを/tmp/stdboth_file
に入れるだけで、/tmp/stderr_file
に書き込むことはありません。
zsh
(およびzsh
のみ)とそのmultios
機能を使用する場合:
your-cmd 2> stdout+stderr.log >&2 2> stderr.log
Fd 2は2回リダイレクトされるため、zsh
は内部tee
を実装して、両方のファイルに送信します。
bash
(またはBourneのようなシェル)を使用すると、次の方法でtee
ingを手動で実行できます。
{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
(your-cmd
の終了ステータスは失われますが、zsh
は$pipestatus[1]
にありますが、bash
は"${PIPESTATUS[0]}"
にあります(stderr+stdout.log
へのリダイレクトが失敗しなかった場合))。
your-cmd
のpidを記録するには、次のようにします。
{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
yash
を使用すると、プロセスリダイレクト機能:
your-cmd > stdout+stderr.log 2>(tee stderr.log)
(ただし、yash
はそのtee
コマンドの終了を待機しないため、その後次のコマンドを実行するまでにログファイルが完了しない場合があることに注意してください)。
bash
、zsh
、およびksh93
のプロセス置換を使用して、同様の(および同じ警告)を行うことができます。
{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log
バックグラウンドで実行してpidを取得するには:
(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!
rc
の場合:
{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
rc
のパイプを使用すると、パイプに接続するファイル記述子を指定できます。他のシェルでは、常に左側のコマンドのfd 1と右側のコマンドのfd0です(したがって、ファイル記述子をシフトするために、上記のfd 3で少し踊ります)。 rc
は、your-cmd
またはtee
のいずれかが失敗した場合に失敗を報告しますが、正確な数は失われる可能性があります。