【问题标题】:Why does less change order of output?为什么 less 改变输出顺序?
【发布时间】:2014-02-21 17:44:40
【问题描述】:

我正在运行一个 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,不应该少保留顺序吗?

【问题讨论】:

  • less 确实保留了它收到的订单;但是,在写入管道时,不能保证 shell 如何交错标准错误和标准输出。

标签: c shell unix terminal


【解决方案1】:

当你运行时:

./svnfixversion ./ 1.5 --verbose

它的stdout 是行缓冲的,stderr 是非缓冲的。

在:

./svnfixversion ./ 1.5 --verbose 2>&1 | less

它的stdout 是完全缓冲的,stderr 是非缓冲的。

./svnfixversionFILE* stdout 的缓冲模式是这两种情况下输出不同的原因。

如果您希望第二个输出与第一个相同,请将stdout 缓冲模式设置为使用stdbuf 应用程序缓冲的行:

stdbuf --output=L ./svnfixversion ./ 1.5 --verbose 2>&1 | less

在现代bash 中,您可以将2>&1 | 替换为更短的|&


幕后发生的事情是,在调用main() 之前的程序启动glibc 调用isatty(STDOUT_FILENO) 以确定stdout 是否连接到终端。如果是这样,stdout 是行缓冲的,否则是全缓冲的。 stderr 始终没有缓冲。

【讨论】:

  • 我知道 stderr 没有缓冲,但我从未听说过行缓冲与完全缓冲...非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 2021-03-11
  • 2017-08-18
  • 2018-06-13
  • 2019-11-30
相关资源
最近更新 更多