![管道到 grep 到定向运算符(到文件)](https://linux22.com/image/1196393/%E7%AE%A1%E9%81%93%E5%88%B0%20grep%20%E5%88%B0%E5%AE%9A%E5%90%91%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%88%E5%88%B0%E6%96%87%E4%BB%B6%EF%BC%89.png)
有效的方法:以下三种方法之一:
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-buffered
或stdbuf -o0 grep
有关 stdio 中缓冲区的一般深入信息:http://www.pixelbeat.org/programming/stdio_buffering/