【发布时间】:2011-03-28 19:04:25
【问题描述】:
有没有办法在没有输出缓冲的情况下运行 shell 命令?
例如,hexdump file | ./my_script 只会将来自 hexdump 的输入以缓冲块的形式传递给 my_script,而不是逐行传递。
其实我想知道一个通用的解决方案如何使任何命令不缓冲?
【问题讨论】:
有没有办法在没有输出缓冲的情况下运行 shell 命令?
例如,hexdump file | ./my_script 只会将来自 hexdump 的输入以缓冲块的形式传递给 my_script,而不是逐行传递。
其实我想知道一个通用的解决方案如何使任何命令不缓冲?
【问题讨论】:
试试stdbuf,它包含在 GNU coreutils 中,因此几乎可以用于任何 Linux 发行版。这会将输入、输出和错误的缓冲区长度设置为零:
stdbuf -i0 -o0 -e0 command
【讨论】:
unbuffer 效果更好。 stdbuf 传递了任何信号(在我的情况下为 SIGUSR2)我发送给它到 command(这是我想要发生的),而 unbuffer 似乎不想这样做。
stdbuf -o0 bash 运行了一个完整的会话,其中包含我所有可用的脚本和别名,并且在任何命令上都没有输出缓冲,这正是我想要的。缓冲当然会在退出此bash 实例时恢复。我正在使用 Ubuntu 16.04。
if [[ "$0" == "-bash" ]]; then exec /usr/bin/stdbuf -i0 -oL -eL /bin/bash -l; fi
exec 模式为我工作,用于将输出发送到日志文件,所有输出行都缓冲而不是完全禁用缓冲:exec > >(stdbuf -i0 -oL -eL awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0 }' | stdbuf -i0 -oL -eL tee "$LOGFILE") 2>&1
expect 包中的命令 unbuffer 禁用输出缓冲:
Ubuntu Manpage: unbuffer - unbuffer output
示例用法:
unbuffer hexdump file | ./my_script
【讨论】:
AFAIK,如果没有丑陋的黑客,你就无法做到这一点。写入管道(或从中读取)会自动打开完全缓冲,您对此无能为力:-(。“行缓冲”(这是您想要的)仅在读/写终端时使用。丑陋的黑客正是这样做的:他们将程序连接到伪终端,以便管道中的其他工具以行缓冲模式从该终端读取/写入。这里描述了整个问题:
该页面还有一些建议(前面提到的“丑陋黑客”)做什么,即使用unbuffer 或使用LD_PRELOAD 拉一些技巧。
【讨论】:
您还可以使用script 命令将hexdump 的输出设为行缓冲(hexdump 将在伪终端中运行,这会欺骗hexdump 使其认为将其标准输出写入终端,并且不是管道)。
# 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
【讨论】:
stdbuf 失败了,但脚本就像一个魅力。程序在通过管道传输到tee 时缓冲输出,但在终端中运行时不缓冲。所以,脚本有效!谢谢!
script 的 man 页面由 this 引用,“某些交互式命令,例如 vi(1),在打字稿文件中创建垃圾。脚本最适用于不操纵屏幕的命令,其结果旨在模拟硬拷贝终端。”
应该使用 grep 或 egrep "--line-buffered" 选项来解决这个问题。无需其他工具。
【讨论】: