bash:强制exec'd进程具有无缓冲的stdout

我有一个脚本,如:

#!/bin/bash exec /usr/bin/some_binary > /tmp/my.log 2>&1 

问题是some_binary将所有的日志logging发送到标准输出,而缓冲使得我只能看到几行输出。 这是令人讨厌的东西卡住了,我需要看看最后一行说什么。

有没有办法使stdout无缓冲之前,我会执行这将影响some_binary,所以它有更多有用的日志logging?

(包装脚本只是在exec之前设置一些环境variables,所以perl或python中的解决scheme也是可行的。)

您可能会发现expectunbuffer脚本可能会有所帮助。

GNU coreutils-8.5也有stdbuf命令来修改I / Ostream缓冲。

http://www.pixelbeat.org/programming/stdio_buffering/

所以,在你的例子中,只需调用:

 exec stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1 

这将允许文本逐行显示(一旦一行完成,并在C)中的行尾"\n"字符)。 如果您确实需要立即输出,请改用-o0

如果您不想通过unbuffer命令引入依赖关系,那么这种方式可能更合意。 另一方面,如果你不得不愚蠢地认为它面临着一个真正的标准输出,那么就需要这种unbuffer some_binary方式。

一些命令行程序可以select修改它们的标准输出stream缓冲行为。 所以如果C源可用的话,这就是要走的路

 # two command options ... man file | less -p '--no-buffer' man grep | less -p '--line-buffered' # ... and their respective source code # from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c if(nobuffer) (void) fflush(stdout); # from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c if (line_buffered) fflush (stdout); 

作为使用expect的非缓冲脚本或修改程序源代码的替代方法,您也可以尝试使用脚本(1)来避免由pipe道引起的stdout打嗝:

请参阅: 欺骗一个应用程序,认为它的stdin是交互式的,而不是pipe道

 # Linux script -c "[executable string]" /dev/null # FreeBSD, Mac OS X script -q /dev/null "[executable string]" 

GNU Coreutils-8包含一个名为stdbuf的程序,它实质上是LD_PRELOAD技巧。 它在Linux上工作,据说在BSD系统上工作。

我search了互联网寻找答案,而这一切都为uniq工作,这是太顽固了,除了stdbuf以外的任何东西都缓冲:

{piped_command_here} | stdbuf -oL uniq | {more_piped_command_here}

环境variables可以将terminalIO模式设置为无缓冲。

导出NSUnbufferedIO = YES

这将设置C和O-Cterminal输出命令的无缓冲terminal。