管道是否可以在任何POSIX shell中创建子shell?


shell脚本按预期运行.

trap 'echo exit' EXIT

foo()
{
    exit
}

echo begin
foo
echo end

这是输出.

$sh foo.sh
begin
exit

这表明脚本在执行foo时退出.

现在看下面的脚本.

trap 'echo exit' EXIT

foo()
{
    exit
}

echo begin
foo | cat
echo end

这里唯一的区别是foo的输出正在被输入`cat.现在输出如下所示.

begin
end
exit

这表明在执行foo时脚本不会退出,因为打印了end.

我相信这是因为在bash中管道导致子shell被打开,所以foo | cat相当于(foo)|猫.

在任何POSIX shell中都能保证这种行为吗?我在http://pubs.opengroup.org/onlinepubs/9699919799/的POSIX标准中找不到任何暗示管道必须通向子壳的东西.有人可以确认是否可以依赖这种行为?

最佳答案 在
2.12 Shell Execution Environment你会发现这个引用:

A subshell environment shall be created as a duplicate of the shell environment, except that signal traps that are not being ignored shall be set to the default action. Changes made to the subshell environment shall not affect the shell environment. Command substitution, commands that are grouped with parentheses, and asynchronous lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

这个问题的关键句是

Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment

所以没有扩展(bash用于像lastpipe这样的东西,我认为,对于管道中的第一个元素,但显然不是或者至少不是总是),看起来你可以假设每个部分都有一个子shell管道,但异常意味着你不能指望它.

点赞