我正在运行一个python脚本,当我以详细模式运行它时会生成某些输出。当我将输出传递给less实用程序时,输出的顺序不同。作为参考,该脚本(如果不完全相同)几乎就是这样:
http://svn.apache.org/repos/asf/subversion/trunk/tools/client-side/change-svn-wc-format.py
具体来说,我得到“以下字段的数据”消息,当我运行它而不将输出汇总到less时,此消息最后出现。当我将输出管道输出为less时,输出会首先神秘地出现。
有人可以解释一下吗?
我已确定错误消息会转到stderr,而详细消息会转到stdout。但是,即使我这样做了:
./svnfixversion ./ 1.5 --verbose 2>&1 | less
输出与我刚离开|时的输出不同减。如果stderr被重定向到stdout,那么不应该保留订单吗?
答案 0 :(得分:3)
当你跑步时:
./svnfixversion ./ 1.5 --verbose
其stdout
是行缓冲的,stderr
是非缓冲的。
在:
./svnfixversion ./ 1.5 --verbose 2>&1 | less
其stdout
已完全缓冲,stderr
未缓冲。
./svnfixversion
FILE* stdout
的缓冲模式是导致两种情况下输出不同的原因。
如果您希望第二个输出与第一个输出相同,请将stdout
缓冲模式设置为使用stdbuf
应用程序缓冲的行:
stdbuf --output=L ./svnfixversion ./ 1.5 --verbose 2>&1 | less
在现代bash
中,您可以使用较短的2>&1 |
替换|&
。
在幕后发生的事情是,在调用main()
之前的程序启动glibc
调用isatty(STDOUT_FILENO)
以确定stdout
是否已连接到终端。如果是这样,stdout
是行缓冲的,否则全缓冲。 <{1}}始终是无缓冲的。