stdout到file1,stderr到file2,都正确交错到stdout和文件

vle*_*lee 5 bash redirect stdout stderr tee

鉴于第三方计划,如何同时进行:

  1. 将stdout写入z.stdout
  2. 写stderr到z.stderr
  3. 适当地传递退出代码
  4. 以正确的交错顺序写入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;
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经能够做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
Run Code Online (Sandbox Code Playgroud)

多亏了相关答案通过lhunath和一个朋友,我把它简化为:

delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
Run Code Online (Sandbox Code Playgroud)

但是,我无法获得正确的交错顺序.stderr立即打印,并且(推测缓冲的)stdout最后都打印出来.

1:stderr
3:stderr
5:stderr
7:stderr
9:stderr
0:stdout
2:stdout
4:stdout
6:stdout
8:stdout
Run Code Online (Sandbox Code Playgroud)

运行delayed_interleaved_stdout_stderr.pl本身会以正确的0-9顺序显示.强制stdout正确刷新工作(请参阅注释的fixme部分),但我将无法修改真实文件.

也许我错过了一些基本的东西,我开始怀疑这是否可能:(

vle*_*lee 1

我确认我可以对第三方程序强制执行标准输出刷新。鉴于此,我将与

delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助!