我写了一个程序 capture ,它输出stdout消息以及stderr消息(即printf(),fprintf(stderr,..))
capture
我希望打印信息显示在终端上并保存到日志文件中 .
./capture 2>&1|tee log
但我发现stdout和stderr消息似乎没有在日志文件中按顺序排列 .
输出重定向按顺序写stdout和stderr信息?如果没有,我该怎么办才能使它们井然有序?
输出重定向,因为它保持 write() 调用的顺序 . 重定向仅更改为进程保留的内核中的文件描述符结构,将值从 fd1 复制到 fd2 .
write()
fd1
fd2
你的问题是 *printf() 缓冲输出批处理一些 write() 调用 . 通常不使用 stderr 和 line-buffering 的 stdout 缓冲 . 但是当您将其重定向到管道时,它会切换到 block 缓冲 stdout ,从而延迟输出(请参阅 man stdout ) . 使用 setlinebuf(stdout); 开始手动将缓冲模式设置为行,或者在每个 *printf() 之后使用 fflush(stdout); . 或者只使用原始 write() 调用 . 你可以在 man setlinebuf 中读到这个 .
*printf()
stderr
line-buffering
stdout
block
man stdout
setlinebuf(stdout);
fflush(stdout);
man setlinebuf
实际上你可以在bash中使用 |& 进行重定向 . 查看 man bash 关于 Pipelines .
|&
man bash
Pipelines
1 回答
输出重定向,因为它保持
write()
调用的顺序 . 重定向仅更改为进程保留的内核中的文件描述符结构,将值从fd1
复制到fd2
.你的问题是
*printf()
缓冲输出批处理一些write()
调用 . 通常不使用stderr
和line-buffering
的stdout
缓冲 . 但是当您将其重定向到管道时,它会切换到block
缓冲stdout
,从而延迟输出(请参阅man stdout
) . 使用setlinebuf(stdout);
开始手动将缓冲模式设置为行,或者在每个*printf()
之后使用fflush(stdout);
. 或者只使用原始write()
调用 . 你可以在man setlinebuf
中读到这个 .实际上你可以在bash中使用
|&
进行重定向 . 查看man bash
关于Pipelines
.