如何使任何shell命令的输出无缓冲?


72

有没有一种方法可以运行shell命令而无需输出缓冲?

例如,hexdump file | ./my_script将仅以缓冲块的形式将输入从hexdump传递到my_script,而不是逐行传递。

其实我想知道一个通​​用的解决方案,如何使任何命令都没有缓冲?


Answers:


22

AFAIK,没有丑陋的骇客就无法做到。写入管道(或从管道读取)会自动打开完整缓冲,您对此无能为力:-(。“ Line buffering”(这是您想要的)仅在读取/写入终端时使用。丑陋的黑客正是这样做的:他们将程序连接到伪终端,以便管道中的其他工具以行缓冲模式从该终端读取/写入该问题。

该页面还提供了一些建议(前面提到的“丑陋的hack”),例如,使用unbuffer或使用一些技巧LD_PRELOAD


谢谢。我以前从未听说过伪终端。
bodacydo

143

试试stdbuf,它包含在GNU coreutils中,因此几乎包含在任何Linux发行版中。这会将输入,输出和错误的缓冲区长度设置为零:

stdbuf -i0 -o0 -e0 command

8
这比unbuffer我做得更好。stdbuf传递了任何信号(SIGUSR2就我而言),我发送给了它command(这是我想发生的事情),而unbuffer似乎并不想这样做。
ElDog 2015年

4
stdbuf使用前面提到的LD_PRELOAD技巧之一来执行此操作,因此不适用于静态链接或setuid可执行文件。请参阅讨论这个问题:stackoverflow.com/questions/13644024/...
北欧大型机

7
我发现这非常有用,但有局限性,因为它不会隐式运行脚本。但是,stdbuf -o0 bash使用我所有的脚本和别名运行一个完整的会话,并且在任何命令上都没有输出缓冲,这正是我想要的。在此bash实例退出时,缓冲当然会恢复。我正在使用Ubuntu 16.04。
AFH

2
我非常喜欢这个,我把它放在我的.bash_profile中。if [[ "$0" == "-bash" ]]; then exec /usr/bin/stdbuf -i0 -oL -eL /bin/bash -l; fi
IcarusNM

1
以一种exec将输出发送到日志文件的模式为我工作,所有输出行都已缓冲而不是完全禁用:exec > >(stdbuf -i0 -oL -eL awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0 }' | stdbuf -i0 -oL -eL tee "$LOGFILE") 2>&1
JinnKo


21

您还可以使用该script命令使hexdump行缓冲输出(hexdump将在伪终端中运行,这会诱使用户hexdump考虑将其stdout写入终端而不是管道)。

# cf. http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe/
stty -echo -onlcr
script -q /dev/null hexdump file | ./my_script         # FreeBSD, Mac OS X
script -q -c "hexdump file" /dev/null | ./my_script    # Linux
stty echo onlcr

我使用-f参数进行刷新,不确定是否需要,但可以。
Gringo Suave

以我为例,它stdbuf失败了,但是脚本的作用却很吸引人。程序在将输出通过管道传输到时会缓冲输出tee,但在终端中运行时则不会。因此,脚本有效!谢谢!
TerrenceSun

非常聪明的解决方案,而且有效!!谢谢。:smile:
xmnboy

唯一的问题是:在引用scriptman每页上,“某些交互式命令,例如,在打字稿文件中创建垃圾。脚本最适合不操纵屏幕的命令,其结果旨在模拟硬拷贝终奌站。” vi(1)
RandomDSdevel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.