当通过“$(…)”运行时,bash`set-e`在函数内部重置?

当通过“$(…)”运行时,bash`set-e`在函数内部重置?,bash,shell,Bash,Shell,当通过$(…)扩展调用这些函数时,Bash中的set-e选项似乎在函数内部被重置 这让我很惊讶,我不确定这是否是一个bug。 我在Bash手册页(通常非常彻底)中找不到对这种行为的描述 注:以下是一些其他类似的SO帖子: 但是它们都不涉及$(…),这在手册页中也没有真正讨论过 我也找不到有关这个问题的参考文献 下面是一个小程序来演示该问题: echo“首字母:$-” set-eu echo“设置后:$-” 函数foo(){ echo“内部foo:$-” } 福 功能条(){ 错#我认为这

当通过
$(…)
扩展调用这些函数时,Bash中的
set-e
选项似乎在函数内部被重置

这让我很惊讶,我不确定这是否是一个bug。 我在Bash手册页(通常非常彻底)中找不到对这种行为的描述

注:以下是一些其他类似的SO帖子:

但是它们都不涉及
$(…)
,这在手册页中也没有真正讨论过

我也找不到有关这个问题的参考文献

下面是一个小程序来演示该问题:

echo“首字母:$-”
set-eu
echo“设置后:$-”
函数foo(){
echo“内部foo:$-”
}
福
功能条(){
错#我认为这会立即失败
echo“内部条:$-”
}
#当涉及$(…)构造时,“bar”将运行到完成!
x=$(巴)
echo“我们不应该到这里……但我们到了。”
回音“$x”
对于我来说,在Bash版本
5.0.11(0)-release
上,我得到了以下输出:

首字母:hB
赛后:ehuB
内富:ehuB
我们不应该到这里。。。但我们有。
内杆:轮毂
因此,如您所见,
-u
选项在所有情况下都会“传递”到函数。当函数正常调用时,
-e
选项被传递。但只有在
$(bar)
的特殊情况下,
-e
选项才会重置

有人知道这是记录在案的行为还是可以解释的吗


这对我来说毫无意义(:

集合-e与的行为在 :

生成用于执行命令替换的子shell从父shell继承
-e
选项的值。当不处于POSIX模式时,Bash清除此类子shell中的
-e
选项


这似乎表明您看到的行为是预期的-除非您在POSIX模式下运行,
-e
选项在Bash中的命令替换子shell中未设置(即使
-e
设置最初是继承的,但在子shell开始执行后不久就会更改).不过,这是一种有趣的写作方式。

相关的
页面为您引述了以下内容,首先从该部分开始

命令替换允许命令的输出替换命令名。有两种形式:

         $(command)
   or
         `command`
Bash通过在子shell环境中执行命令来执行扩展,并用命令的标准输出替换命令替换,同时删除所有后续换行符

和来自:

生成用于执行命令替换的子shell从父shell继承-e选项的值。当不处于posix模式时,bash将清除此类子shell中的-e选项

因此,
bar
在子shell中执行,并且由于您没有处于
posix
模式,
-e
选项被清除


set-o posix
添加到脚本的开头,脚本将按预期运行,但在使用此模式时会出现其他情况。

the
$(…)
符号在Bash手册中有描述。但是它没有详细说明与
set-e
的交互。@KamilCuk:我不明白你的意思;你能解释一下吗?这里不涉及子进程,只涉及shell函数。无论如何,导出不会改变我的示例程序中的行为。
只是shell f函数
-命令替换创建一个子进程。噢,有
继承\u errexit
shopt@KamilCuk:这不是真的-您可以通过在shell函数中打印
$$
进行验证。它在内部和外部都是相同的数字。当然,现在请使用
$BASHPID
进行验证。对于
echo$BASHPID;$(echo$BASHPID>&2)
我看到了一个不同的数字。如果你真的想,只要阅读在子shell环境中执行命令的