サードパーティのプログラムを考えると、同時にどのようになりますか?
- stdoutをz.stdoutに書き込みます
- stderrをz.stderrに書き込みます
- 終了コードを適切に渡す
- 両方を正しいインターリーブされた順序でstdoutに書き込みます
これが私が使用しているテストプログラム(delayed_interleaved_stdout_stderr.pl)です:
#!/usr/bin/env perl
use strict;
use warnings;
# fixme: debug, uncomment to force stdout flushing
# use English '-no_match_vars';
# $OUTPUT_AUTOFLUSH = 1;
# use sleeps to simulate delays and test buffering
use Time::HiRes 'sleep';
foreach my $num ( 0..9 ) {
if ( 0 == $num % 2 ) {
print STDOUT $num, ":stdout\n";
}
else {
print STDERR $num, ":stderr\n";
}
sleep 0.25;
}
これまでのところ、私は次の方法で1,2,3を実行できました。
( set -o pipefail; \
( set -o pipefail; delayed_interleaved_stdout_stderr.pl \
| tee z.stdout; exit $? \
) 3>&1 1>&2 2>&3 | tee z.stderr; exit $? \
) 3>&1 1>&2 2>&3
lhunathと友人による関連する回答のおかげで、私はそれを次のように簡略化しました。
delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
しかし、正しいインターリーブ順序を取得できませんでした。stderrはすぐに印刷し、(おそらくバッファリングされた)stdoutは最後にすべての印刷を行います。
1:stderr
3:stderr
5:stderr
7:stderr
9:stderr
0:stdout
2:stdout
4:stdout
6:stdout
8:stdout
delayd_interleaved_stdout_stderr.plを単独で実行すると、適切な0〜9の順序で表示されます。stdoutを強制的にフラッシュすることは適切に機能しますが(コメント付きのfixmeセクションを参照)、実際のファイルを変更することはできません。
たぶん私は何か基本的なものが欠けていて、これがまったく可能かどうか疑問に思い始めています:(