简体   繁体   English

Bash Anonymous Pipes

[英]Bash Anonymous Pipes

When designing a chain of commands to perform a certain task, i ran into the problem that anonymous pipes do not behave like expected. 在设计一系列命令来执行某项任务时,我遇到了匿名管道不像预期的那样行为的问题。 As the original command that i am running is too complex to explain here, i've created an example that shows the problem (i know that all these commands are doing basically nothing). 由于我正在运行的原始命令太复杂而无法在这里解释,我已经创建了一个显示问题的示例(我知道所有这些命令基本上都没有)。 Also, i am using pv to show whether the data is actually copied from input to output. 另外,我使用pv来显示数据是否实际上是从输入复制到输出。

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

This works as expected. 这按预期工作。 (copy data from /dev/zero to /dev/null) (将数据从/ dev / zero复制到/ dev / null)

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

This also works as expected (duplicate the data and send both copies to /dev/null) 这也按预期工作(复制数据并将两个副本发送到/ dev / null)

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

This command only partially works. 此命令仅部分有效。 While the copy from STDIN to STDOUT still works, (one pv will show progress for a short time), the whole command gets stalled by the anonymous pipe, which does not receive anything and thus tee stalls as one of the outputs cannot be written to (I checked this by letting it write to files instead of /dev/null). 虽然从STDIN到STDOUT的副本仍然可以工作,(一个pv会在短时间内显示进度),整个命令会被匿名管道停止,它不会收到任何东西,因此tee停顿,因为其中一个输出无法写入(我通过让它写入文件而不是/ dev / null来检查这一点)。

If anyone has an Idea why this does not work (as expected ?) in bash, i'd be glad for the help. 如果有人知道为什么这不起作用(如预期的那样?)在bash中,我会很高兴得到帮助。

PS: If I use zsh instead of bash, the command runs as expected. PS:如果我使用zsh而不是bash,则命令按预期运行。 Unfortunately, the system this needs to run on has no zsh and there is no way for me to get zsh on that system deployed. 不幸的是,这个需要运行的系统没有zsh,我无法在部署的系统上获得zsh。

Whe you use <( ... ) for process substitution, the process running inside does not have a controlling terminal. 当您使用<( ... )进行进程替换时,内部运行的进程没有控制终端。 But pv always shows its results to the terminal; 但是pv总是向终端显示其结果; if there isn't any, it gets stopped. 如果没有,它就会停止。

If you execute your code and, while it is running, do a ps axf , you will see something like this: 如果您执行代码,并且在运行时执行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

...which tells you that the pv -c executed inside the process substitution (the one below the second bash ) is in T state, stopped . ...告诉你在进程替换中执行的pv -c (第二个bash下面的那个)处于T状态, 停止 It is waiting to have a controlling terminal in order to run. 它正在等待有一个控制终端才能运行。 It does not have any, so it will stop forever, and bash eventually stops sending data to that pipe. 它没有任何东西,所以它会永远停止,而bash最终会停止向该管道发送数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM