【问题标题】:stdout to file1, stderr to file2, both correctly interleaved to stdout and filestdout 到 file1,stderr 到 file2,都正确交错到 stdout 和 file
【发布时间】:2011-08-12 01:22:43
【问题描述】:

给定一个第三方程序,如何同时提供一个:

  1. 将标准输出写入 z.stdout
  2. 将标准错误写入 z.stderr
  3. 适当地传递退出代码
  4. 以正确的交错顺序将两者写入标准输出

这是我一直在使用的测试程序(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

感谢lhunathrelated answer 和一位朋友,我将其简化为:

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

运行延迟_interleaved_stdout_stderr.pl 本身以正确的 0-9 顺序显示。强制标准输出刷新正常工作(请参阅注释的 fixme 部分),但我将无法修改真实文件。

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

【问题讨论】:

  • bash sn-ps 很好——在我看来问题在于 perl 的输出缓冲。如果您能想出一种方法在不修改脚本的情况下取消缓冲输出,那么顺序应该是正确的。我尝试使用 GNU stdbuf 实用程序,但它没有做任何事情。
  • 似乎不太可能有帮助,但请查看您的系统是否有 unbuffer cmd。这值得一试。不可修改的代码是perl吗?祝你好运。
  • 至少有一部分是 Perl;我将与作者合作,尽可能强制刷新标准输出。感谢您的建议!
  • 顺便说一句,如果我要使用:“delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)”并尝试强制 stdout冲洗,我应该更新我的问题并回答我自己的问题,还是不回答这个问题更好?

标签: bash redirect stdout stderr tee


【解决方案1】:

要求 4 是一个棘手的问题。 stdout 和 stderr 的缓冲逻辑隐藏在 libc 中,要更改它,您需要欺骗应用程序以为它正在写入终端。

unbuffer 附带的 expect 包会为你做这件事。警告:即使写入终端,stdout 也是行缓冲的,所以如果您的应用程序没有写入完整的行,那么这将不起作用。

【讨论】:

  • 我删除了需求#4(交错到文件)并将#5移到#4。我还确认我可以为第三方程序强制执行标准输出刷新! /欢呼
【解决方案2】:

我确认我可以为第三方程序强制执行标准输出刷新。有鉴于此,我会选择

delayed_interleaved_stdout_stderr.pl > >(tee z.stdout) 2> >(tee z.stderr >&2)

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 2014-07-29
    • 2014-07-22
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多