两个函数定义,唯一的区别是第一个将local
storage 关键字与赋值组合在一起,而第二个将它们分开:
function foo {
local fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
echo $?
}
function bar {
local fn
fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
echo $?
}
foo
bar
Run Code Online (Sandbox Code Playgroud)
这与“0”然后“1”相呼应。我希望它回声“1”然后是“1”。似乎的值$?
是分配给 local 的结果,而不是命令替换的结果。
为什么 bash 4.2.46(1)-release 会这样?
我认为这种行为是明确记录的,因为它是如此的一个问题(尤其是在运行 bash 脚本时-o errexit
!),但它似乎没有。我的手册副本如下( about
global
,其行为与local
在函数内时相同):
除非遇到无效选项,否则返回状态为零,尝试使用“-f foo=bar”定义函数,尝试将值分配给只读变量,尝试分配值对于不使用复合赋值语法 [...] 的数组变量,名称之一不是有效的 shell 变量名称,尝试关闭只读变量的只读状态,尝试关闭数组数组变量的状态,或者尝试使用 -f 显示不存在的函数。
因此,它似乎local
不是其他编程语言中所期望的关键字:当向 提供类似赋值的参数时local
,它不符合初始化条件;相反,local
内置命令负责进行赋值,并且返回码是它local
自己的,而不是可能在初始化程序中运行的代码,并且该返回码在列出的条件列表中只会是非零的以上。
也许从更字面的意义上回答这个问题,正如 bishop 在评论中提到的那样,曾有人问 bash 维护者 Chet Ramey 是否会考虑local
在分配期间反射失败,并回答说,本质上,分配不是
local
主要任务:
因为这不是 local 及其兄弟姐妹 [...] 所做的。这些内置函数用于分配和修改变量属性。作为一个附加功能,它们同时支持赋值,但重要的功能是属性设置。他们不需要知道值是如何计算的。[...] 由于函数正在设置属性或值,退出状态应反映是否成功。
值得注意的是,在zsh
shell 中也可以观察到相同的行为。
解决方法是将这两个操作分开:
local variable
variable=$( somecommand )
exit_status=$?
Run Code Online (Sandbox Code Playgroud)