这段代码中没有使用tee定义,但是,正如Daenyth所说,wc命令在tee传递完数据之前不会完成 - 因此通常情况下,tee在将数据传递给awk之后就已经完成了。在这种情况下,让awk来计数可能更好一些。
echo -ne {one,two,three,four}\\n | \
awk '{print "awk processing line " NR ": "$0} END {print "Awk saw " NR " lines"}'
缺点是在完成之前它不会知道数字(要知道数字需要缓冲数据)。在您的示例中,tee和wc的stdout都连接到同一个管道(awk的stdin),但顺序未定义。cat(和大多数其他管道工具)可用于按已知顺序组装文件。
还有更高级的管道技术可以使用,例如bash协处理器(coproc)或命名管道(mkfifo或mknod p)。后者可以为您在文件系统中获取名称,这些名称可以传递给其他进程,但您必须清理它们并避免冲突。tempfile或$$可能对此有用。管道不用于缓冲数据,因为它们通常具有有限的大小,并且将简单地阻止写入。
管道不适用的示例:
mkfifo wcin wcout
wc -l < wcin > wcout &
yes | dd count=1 bs=8M | tee wcin | cat -n wcout - | head
这里的问题是tee会陷入困境,试图将内容写入cat,而cat希望先完成wcout。对于从tee到cat的管道来说,数据太多了。
关于dmckee答案的编辑:
是的,顺序可能是可重复的,但不能保证。这是一个规模、调度和缓冲区大小的问题。在这个GNU/Linux盒子上,示例在几千行后就开始分裂了。
seq -f line%g 20000 | tee >(awk '{print "*" $0 "*"}' ) | \
(awk '{print "this is awk: "$0}') | less
this is awk: line2397
this is awk: line2398
this is awk: line2*line1*
this is awk: *line2*
this is awk: *line3*