读取管道中的变量时会发生什么?

What happens when reading into a variable in a pipeline?

echo hello | read str
echo $str

这个 read 在管道之后执行,这意味着 echo 的输出被读入 str - 但因为它在管道之后, str 现在位于父 shell 无法读取的子 shell 中。

str 的内容发生了什么变化?管道是否创建一个子 shell,然后一旦内容被读入 str,父进程是否终止子进程并且 str 被擦除 - 或者 str 住在 shell 以外的地方?比如我们如何查看 subshell 中的内容?我们可以从父 shell 访问子 shell 吗?

${str} 的值仅在子shell 的生命周期内存在。管道的左侧或右侧是父级还是子级shell 取决于具体的shell 和shell 版本。

Bash 4.x 有一个选项 shopt -s lastpipe 到 运行 父级 shell 管道的最后一个命令,就像 ksh93 默认情况下所做的那样。 $str 的值将保留。

在您的示例中,$str 存在于子 shell 中,默认情况下,它会在该行结束后消失。子进程不能修改其父进程。

除了更改 shell 选项 lastpipe 之外,您还可以更改代码以避免使用管道。在这种情况下,您可以使用:

read str < <(your command) 
# or
str=$(your command)

这两个都创建子shells,但是$str被分配给父进程。