【问题标题】:How do these process substitutions work?这些流程替换如何工作?
【发布时间】:2016-11-19 10:35:22
【问题描述】:
谁能解释一下这些流程替换是如何工作的。
(echo "YES")> >(read str; echo "1:${str}:first";)> >(read sstr; echo "2:$sstr:two")> >(read ssstr; echo "3:$ssstr:three")
输出
1:2:3:YES:3:2:first
我发现,'ssstr'-Substitution 得到 FD 60、sstr FD 61 和 str FD 62。(从右到左)
但是 (echo "YES") 是如何连接到 FD60 的输入的,以及 FD60 的输出与输入 FD61 等等,最后 FD62 在终端上打印出来?
都违背了两个重定向的方向。
它们是如何嵌套的,又是如何连接的?
让我发疯。
泰。
【问题讨论】:
标签:
bash
shell
redirect
substitution
process-substitution
【解决方案1】:
首先,不要真的写这样的代码:)
进程替换是构造>(...)。 (...)> 不是一个特定的构造;它只是一个子shell,后跟一个输出重定向。
此示例是单个命令 (echo "YES") 后跟三个输出重定向
> >(read str; echo "1:${str}:first";)
> >(read sstr; echo "2:$sstr:two")
> >(read ssstr; echo "3:$ssstr:three")
最后一个是实际应用于原始命令的那个;像echo word >foo >bar >baz 这样的东西会创建所有三个文件,但echo 的输出只会写入baz。
同样,所有三个进程替换都会启动一个新进程,但输出YES 仅写入最后一个。所以read ssstr 的输入来自echo YES。
在这一点上,我认为您看到了未定义的行为。三个进程替换以它们创建的相反顺序运行,就好像操作系统在创建下一个进程时将每个进程推入堆栈,然后通过将它们从堆栈中弹出来安排它们,但我不认为这个顺序是任何东西都可以保证。
不过,在每种情况下,每个进程替换的标准输入都固定为命令的标准输出,即刚刚运行的其他进程替换。换句话说,该命令最终类似于
echo YES | {
read ssstr
echo "3:$ssstr:three" | {
read sstr
echo "2:$sstr:two" | {
read str
echo "1:$str:one"
}
}
}