Bash匿名pipe道

当devise一系列命令来执行某个任务时,我遇到了匿名pipe道不像预期那样的问题。 由于我正在运行的原始命令太复杂了,所以在这里我已经创build了一个显示问题的例子(我知道所有这些命令基本上什么都没有做)。 此外,我使用PV来显示数据是否实际上从input复制到输出。

cat /dev/zero | pv > /dev/null 

这按预期工作。 (将数据从/ dev / zero复制到/ dev / null)

 cat /dev/zero | tee /dev/null | pv > /dev/null 

这也按预期工作(复制数据并将两个副本发送到/ dev / null)

 cat /dev/zero | tee >(pv -c > /dev/null) | pv -c > /dev/null 

这个命令只有部分工作。 虽然从STDIN到STDOUT的拷贝仍然有效,(一个pv会在短时间内显示进度),但是整个命令会被匿名pipe道阻塞,而这个匿名pipe道并没有收到任何东西,因此其中一个输出不能被写入(我通过让它写入文件而不是/ dev / null来检查这一点)。

如果有人有一个想法,为什么这不起作用(如预期?)在bash中,我会很高兴的帮助。

PS:如果我使用zsh而不是bash,命令按预期运行。 不幸的是,这个需要运行的系统没有zsh,并且我没有办法在部署的系统上获得zsh。

Solutions Collecting From Web of "Bash匿名pipe道"

当你使用<( ... )进行进程替换时,运行在里面的进程没有控制终端。 但是, pv总是向终端显示结果; 如果没有,就停下来。

如果你执行你的代码,并在运行的时候执行ps axf ,你会看到如下所示:

 23412 pts/16 S 0:00 \_ bash 24255 pts/16 S+ 0:00 \_ cat /dev/zero 24256 pts/16 S+ 0:00 \_ tee /dev/fd/63 24258 pts/16 S 0:00 | \_ bash 24259 pts/16 T 0:00 | \_ pv -c 24257 pts/16 S+ 0:00 \_ pv -c 

…它告诉你,在进程替代(第二个bash之下)内执行的pv -c处于T状态, 停止 。 有一个控制终端正在等待运行。 它没有任何东西,所以它会永远停止,并且bash最终会停止发送数据到管道。