tee命令通过管道传输到grep并重定向到文件

3

我想在bash中使用以下命令:

(while true; do date; sleep 1;done) | tee out.out 2>&1 | grep ^[A-Z] >log.log 2>&1 &

很不幸,在任务完成之前(例如通过杀死sleep命令的ppid),文件log.log是空的,但文件out.out包含了预期的内容。

  1. 我首先想要了解发生了什么。
  2. 我想要修复这个问题。

2
grep在处理文件时会缓存它。使用grep --line-buffered '^[A-Z]'使其在读取行时立即输出。顺便提一下,注意我在正则表达式周围加上了引号--这里不太可能出现问题,但是如果没有引号,模式可能会在传递给grep之前被扩展为shell通配符模式,这将产生奇怪的结果。 - Gordon Davisson
1个回答

3
为了解决这个问题,您需要使grep进行行缓冲。这可能取决于实现方式,但在BSD grep(与Mac OS X一起提供)上,您只需将--line-buffered选项添加到grep中即可:”最初的回答“
(while true; do date; sleep 1;done) | tee out.out 2>&1 | grep --line-buffered ^[A-Z] >log.log 2>&1 &

来自 grep 手册:

最初的回答:

--line-buffered
             Force output to be line buffered.  By default, output is line buffered when standard output is a terminal and block buffered otherwise.

你可以通过将输出定向到标准输出来验证这种行为:

实际上,你可以将其转换成以下代码:

(while true; do date; sleep 1;done) | tee out.out 2>&1 | grep ^[A-Z] 2>&1 &

在这种情况下,您不需要显式地按行缓冲,因为这是默认设置。但是,当您重定向到文件时,您必须明确设置该行为。"最初的回答"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接