输出重定向是不是按顺序写入 stdout 和 stderr 信息?

Posted

技术标签:

【中文标题】输出重定向是不是按顺序写入 stdout 和 stderr 信息?【英文标题】:Does output redirection write stdout and stderr info in order?输出重定向是否按顺序写入 stdout 和 stderr 信息? 【发布时间】:2016-01-13 01:29:07 【问题描述】:

我写了一个程序capture,它输出stdout消息和stderr消息(即printf(), fprintf(stderr,..))

我希望打印信息显示在终端上并保存到日志文件中。

  ./capture 2>&1|tee log

但我看到 stdout 和 stderr 消息在日志文件中似乎不按顺序排列。

输出重定向是否按顺序写入标准输出和标准错误信息? 如果没有,我该怎么做才能使它们按顺序排列?

【问题讨论】:

【参考方案1】:

输出重定向保持您的write() 调用的顺序。重定向仅更改内核中为进程保留的文件描述符结构,将值从fd1 复制到fd2

您的问题是 *printf() 缓冲输出批处理一些 write() 调用。对于stderrline-bufferingstdout 通常不使用缓冲。但是当你将它重定向到管道时,它会切换到blockstdout 缓冲,从而延迟输出(参见man stdout)。将缓冲模式改为手动在开头使用setlinebuf(stdout);,或在每个*printf() 之后使用fflush(stdout);。或者只使用原始的write() 调用。您可以在man setlinebuf 中阅读相关内容。

实际上,在 bash 中,您也可以使用 |& 进行重定向。查看man bash 关于Pipelines

【讨论】:

以上是关于输出重定向是不是按顺序写入 stdout 和 stderr 信息?的主要内容,如果未能解决你的问题,请参考以下文章

使用系统命令将stdout和stderr输出重定向到文件在perl中不起作用[重复]

输入输出重定向

Linux 重定向与管道符

Linux管道符重定向与环境变量

I/O重定向

搞懂 fflush(stdout)