如何将标准输出和标准错误重定向到管道,但保持它们的顺序



我希望能够从子进程独立读取stdout/stderr(以及我正在引入的一个新的stdlog),对这些流做一些事情,并以相同的顺序将它们写入屏幕和日志文件。

因此,例如,如果子进程想要对标准输出说"aa",然后对标准输出说"bb",然后再对标准输出说"cc",那么我希望在屏幕上看到"aabbcc"。如果我看到"aaccbb",我可以容忍它(我猜这是没有办法的),但我肯定不希望看到"aacbbc"(在一个bug块"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,并且可以跨unix移植。

注意:代码在github上。整个思想是捕获被监视进程的确切输出,并将其存储在日志文件中。在从stderr或stdout写入输出之前,在日志文件中写入诸如"err"或"std"之类的标记,以便稍后可以根据stdout和stderr重新生成进程的确切输出。

谢谢

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

proc2读取数据的顺序只取决于proc1写入数据的顺序。这个顺序只依赖于proc1。

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

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

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

最新更新