【问题标题】:How to redirect stdout and stderr to a pipe but keep them ordered如何将 stdout 和 stderr 重定向到管道但保持有序
【发布时间】:2013-01-17 17:01:29
【问题描述】:

我希望能够从子进程中独立读取 stdout/stderr(以及我正在引入的新 stdlog),对这些流执行某些操作,并将它们写入屏幕和日志文件中顺序。

因此,例如,如果子进程想对 stdout 说“aa”,然后对 stderr 说“bb”,然后再对 stdout 说“cc”,我想在屏幕上看到“aabbcc”。如果我看到“aaccbb”,我可以忍受(我想这是没办法的),但我当然不想看到“aacbbc”(写在一个错误块“cc”中的东西被拆分)。

所以,这是我想出的流程层次结构:

(P) parent process
\_ (O) logger for stdout
\_ (E) logger for stderr
\_ (C) monitored process
  • (C) 标准输出使用管道连接到 (O) 进程,该进程写入日志文件和标准输出
  • (C) stderr 使用管道连接到 (E) 写入日志文件和 stderr 的进程

问题在于,根据 (O) 和 (E) 的调度时间,一般输出(由 (O) 和 (E) 的输出组成)可能会出现乱序。

有没有办法:

  • 有完美的订购吗?我想没有,但也许有一个解决方案......
  • 至少确切地知道在 (O) 和 (E) 进程中要读取多少字节,以便我可以将它们合二为一?

而且,最好使用 python,并且可以跨单元移植。

注意:代码位于github。整个想法是捕获被监视进程的确切输出,并将其存储在日志文件中。在从 stderr 或 stdout 写入输出之前写入日志文件标记,例如“\0err\0”或“\0std\0”,以便我以后可以从进程中重新生成准确的输出,同时尊重 stdout 和 stderr。

谢谢

【问题讨论】:

  • 这些东西的顺序有点难以预测。具体来说,stdout 经常会被缓冲,而stderr 不会。因此,根据缓冲区大小,当使用相同的输入运行相同的程序时,您可能会得到不同的顺序。
  • 可能不太有帮助,但是:“如果我看到“aaccbb”,我可以容忍它”——这就是为什么记录器程序倾向于将标准输出与标准错误完全分开,所以你总是以“aaccbb”,即首先是所有标准输出,然后是所有标准错误。我认为没有更好的方法,除了对进程 C 的源代码进行更改。(终端将同一管道连接到 stdout 和 stderr,这可行,但具有终端无法区分 stdout 和 stderr 的效果全部。)

标签: python unix file-io posix pipe


【解决方案1】:

如果您将 stdout 和 stderr 重定向到同一管道(即proc1 2>&1 | proc2),那么您将无法控制管道上的顺序,因为它们现在完全相同。 stdout 和 stderr 在操作系统中的路径相同。

“proc2”读取数据的顺序仅取决于“proc1”写入数据的顺序。 那个顺序只依赖于proc1。

通常,进程会像这样缓冲数据:

  • stdout 被缓冲,但如果输出是 TTY,则刷新每个换行符,否则当缓冲区已满时。
  • stderr 是无缓冲的,每次写入都会立即刷新。

您可以弄乱 python 缓冲区或使 stdout 和 stderr 完全相同,但也许最简单的方法是尝试python -u ... 使所有输出都没有缓冲。这样,来自 proc1 的每个写入都应该以相同的顺序出现在 proc2 中。

【讨论】:

    猜你喜欢
    • 2015-06-21
    • 2014-07-22
    • 1970-01-01
    • 2020-09-26
    • 2012-08-07
    • 1970-01-01
    • 2011-05-23
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多