在设计执行特定任务的命令链时,我遇到了匿名管道的行为与预期不同的问题。由于我运行的原始命令太复杂,无法在此处解释,因此我创建了一个示例来显示问题(我知道所有这些命令基本上什么也没做)。另外,我使用 pv 来显示数据是否实际上从输入复制到输出。
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 将在短时间内显示进度),但整个命令会被匿名管道停止,该管道不会接收任何内容,因此 tee 会停止,因为输出之一无法写入(我通过让它写入文件而不是 /dev/null 来检查这一点)。
如果有人知道为什么这在 bash 中不起作用(如预期?),我会很高兴获得帮助。
PS:如果我使用 zsh 而不是 bash,该命令将按预期运行。不幸的是,需要运行的系统没有 zsh,我无法在部署的系统上获取 zsh。
当你使用<( ... )
对于进程替换,内部运行的进程没有控制终端。但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
...这告诉你pv -c
在进程替换中执行(第二个下面的那个)bash
) is in T
state, stopped。它正在等待控制终端才能运行。它没有任何东西,所以它将永远停止,并且bash
最终停止向该管道发送数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)