不合规的重定向头部问题

9
在回复 通过 tee 将文件传递给 tail 和 head 时,当处理大文件时,以下结构中的 head 出现了奇怪的行为:
#! /bin/bash
for i in {1..1000000} ; do echo $i ; done > /tmp/n

( tee >(sed -n '1,3p'        >&3 ) < /tmp/n | tail -n2 ) 3>&1 # Correct
echo '#'
( tee >(tac | tail -n3 | tac >&3 ) < /tmp/n | tail -n2 ) 3>&1 # Correct
echo '#'
( tee >(head -n3             >&3 ) < /tmp/n | tail -n2 ) 3>&1 # Not correct!?

输出:

1
2
3
999999
1000000
#
1
2
3
999999
1000000
#
1
2
3
15504
15

问题:

为什么最后一行的输出与前两行不同?

1个回答

9
这是因为当head传输前三行时,它立即退出。随后,tee被SIGPIPE杀死,因为它正在写入的“FILE”管道的读取端已关闭,但在成功输出一些行到其标准输出之前尚未关闭。
如果只执行以下命令:
tee >(head -n3 >/dev/null) < /tmp/n

你将更好地了解发生了什么。
另一方面,tac会读取整个文件因为它必须反转它,sed也是如此,可能是为了保持一致性。

谢谢。我现在明白了。我甚至可以像这样添加 cat ( tee >(head -n3 >&3; cat > /dev/null ) < /tmp/n | tail -n2 ) 3>&1 使其正常工作。 - choroba
不用谢 :) 不过,我认为在那部分使用 sed 会更清晰。 - spbnick
2
请注意,对于小于5行的文件,其中至少有一些将会输出两次。 - spbnick

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