管道到 grep 到定向运算符(到文件)

管道到 grep 到定向运算符(到文件)

有效的方法:以下三种方法之一:

ping 8.8.8.8 | grep 3  // this will steadily output any ping with the number 3 somewhere in the line to the terminal
ping 8.8.8.8 > fileping //this will silently add all the ping output to the file 'fileping'
tee filetee < <(ping 8.8.8.8) // this will show the pings in terminal AND add them to the file

不起作用的是:上述两种组合:

ping 8.8.8.8 | grep 3 > fileping  // this will run, but silent, and the file stays empty
tee filetee < <(grep 3 < <(ping 8.8.8.8)) // will also run silent, leave empty file

它应该做什么:获取 ping 8.8.8.8 的输出,对其进行 grep,然后将结果添加到文件中

根据steeldriver评论中的建议,我尝试了

ping 8.8.8.8 | grep --line-buffered 3 | tee fileping  // this will run, output the filtered pings to terminal, and fill the file.
ping 8.8.8.8 | grep --line-buffered 3 > fileping  // this will run, silently, and fill the file.

所以实际任务成功了。耶!将深入研究 --line-buffered 以找出原因

这主要是为了理解底层原理,因此解释为什么它不起作用的答案可能与使用不同于“|”和“<”的原理的命令一样好

答案1

因此,如果输出连接到管道(“|”)或重定向(“>”)到文件,则 grep 会进行缓冲。根据缓冲区的大小(取决于操作系统),例如,它可能会在输出前累积 4096 字节的输出。

在我上面的例子中,数据的增加太慢了,我没有注意到这一点,我在缓冲区满之前关闭了该过程,导致数据丢失。

添加--line-buffered到 grep 命令将确保它在遇到换行符时立即刷新。或者,可以在命令前加上前缀stdbuf -oL(也进行行缓冲,但并非特定于 grep)或stdbuf -o0(将缓冲区减少到 0,强制刷新,也适用于不仅限于 grep)

因此grep,请使用grep --line-bufferedstdbuf -o0 grep

有关 stdio 中缓冲区的一般深入信息:http://www.pixelbeat.org/programming/stdio_buffering/

相关内容