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

Bash tee命令通过管道传输到grep并重定向到文件,bash,tee,Bash,Tee,我想在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具有预期的内容 我首先想知道发生了什么 我想解决这个问题 为了解决这个问题,需要对grep行进行缓冲。这可能取决于实现,但在BSD grep(

我想在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
具有预期的内容

  • 我首先想知道发生了什么
  • 我想解决这个问题

  • 为了解决这个问题,需要对
    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.
    
    实际上,您可以通过输出到STDOUT来验证该行为:

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

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

    grep
    在文件处理时缓冲该文件。使用
    grep--line buffered'^[A-Z]'
    使其在读取行时立即输出行。顺便说一句,请注意,我在正则表达式周围加了引号——这不太可能是个问题,但是如果没有引号,该模式可能会在传递给
    grep
    之前扩展为shell通配符模式,这会产生奇怪的结果。