给定一个第三方程序,如何同时:
- 将标准输出写入 z.stdout
- 将标准错误写入 z.stderr
- 适当地传递退出代码
- 以正确的交错顺序将两者写入标准输出
这是我一直在使用的测试程序(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
单独运行delayed_interleaved_stdout_stderr.pl 以正确的0-9 顺序显示。强制 stdout 刷新可以正常工作(请参阅注释的 fixme 部分),但我将无法修改真实文件。
也许我错过了一些基本的东西,我开始怀疑这是否可能:(