Bash Anonymous Pipes

Fab*_*ias 10 linux bash pipe anonymous-pipes

在设计一系列命令来执行某项任务时,我遇到了匿名管道不像预期的那样行为的问题.由于我正在运行的原始命令太复杂而无法在此解释,我创建了一个显示问题的示例(我知道所有这些命令基本上都没有做).另外,我使用pv来显示数据是否实际上是从输入复制到输出.

cat /dev/zero | pv > /dev/null
Run Code Online (Sandbox Code Playgroud)

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

cat /dev/zero | tee /dev/null | pv > /dev/null
Run Code Online (Sandbox Code Playgroud)

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

cat /dev/zero | tee >(pv -c > /dev/null) | pv -c > /dev/null
Run Code Online (Sandbox Code Playgroud)

此命令仅部分有效.虽然从STDIN到STDOUT的副本仍然可以工作,(一个pv会在短时间内显示进度),整个命令会被匿名管道停止,它不会收到任何东西,因此tee停顿,因为其中一个输出无法写入(我通过让它写入文件而不是/ dev/null来检查这一点).

如果有人知道为什么这不起作用(如预期的那样?)在bash中,我会很高兴得到帮助.

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

Jua*_*des 2

当您使用<( ... )进程替换时,内部运行的进程没有控制终端。但pv总是向终端显示其结果;如果没有,它就会停止。

如果您执行代码并在其运行时执行 a 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
Run Code Online (Sandbox Code Playgroud)

...这告诉您pv -c在进程替换中执行的进程(第二个下面的那个bash)处于T状态,stopped。它正在等待控制终端才能运行。它没有任何数据,因此它将永远停止,并bash最终停止向该管道发送数据。