bri*_*ice 3 linux unix bash shell command-line
我在对 make 输出进行 grep 过滤时遇到问题。特别是,
make target 2>&1 | grep -E --color=never "^make.*"
Run Code Online (Sandbox Code Playgroud)
按预期工作,但以下内容不会向控制台打印输出:
make target 2>&1 | grep -E --color=never "^make.*" | cat
Run Code Online (Sandbox Code Playgroud)
我错过了一些明显的东西吗?为什么第一个命令输出而不是第二个?是否与某种 IO 缓冲有关?还是我只是愚蠢?
[编辑]: cat
只是我要使用的实际命令的最小测试用例占位符。
[编辑]:这似乎不是 grep 的问题,因为用ack替换它会导致相同的行为。
[编辑]: cat 是占位符的脚本:
#!/bin/bash
cat - \
| grep -E --color=never "^.*warning:.*|^.*error:.*|^make.*[Ee]rror.*|^make.*" \
| hilite.sh -r "^.*warning:.*" -f yellow -B \
| hilite.sh -r "^.*error:.*" -f red -B \
| hilite.sh -r "^make.*[Ee]rror.*" -f red -B \
| hilite.sh -r "^make.*" -f magenta
Run Code Online (Sandbox Code Playgroud)
[编辑]:我认为这是一个缓冲/IO 问题。我让构建在 w/e 上运行,并将查看它是否最终在需要的地方获得输出!
可能grep
是检测到它没有写入 TTY,因此它缓冲了更多的输出,而不是在其通常的行缓冲模式下运行(即,您会看到找到的每一行)。这种行为更有效,因为它导致更少的write()
系统调用,但如果您是等待流水线输出的用户,那么它可能有点误导。
如果您使用的是 GNU grep
(并且基于您的 linux 标签,我假设您是),请查看该--line-buffered
选项,该选项将强制grep
在更熟悉的行缓冲模式下工作。从技术上讲,这可能会降低grep
(如手册页中所述)的性能,但由于您正在查看实时构建的输出,我怀疑它会在这方面产生任何影响。