bash 外部脚本函数的命令替换接收到不正确的退出状态
bash command substitution on external script function receives incorrect exit status
此示例已在 Mac El Capitan 上使用 bash
进行了测试
main_script.sh:
NOTE: func_a and func_b are identical except for the line that the local variable output
is declared.
func_a () {
local output
output="$(./external.sh some_function)"
if [ $? -eq 0 ];then
echo "A zero result ($?) -> $output <- end"
else
echo "A other result ($?) -> $output <- end"
fi
}
func_b () {
local output="$(./external.sh some_function)"
if [ $? -eq 0 ];then
echo "B zero result ($?) -> $output <- end"
else
echo "B other result ($?) -> $output <- end"
fi
}
func_a
func_b
external.sh:
some_function () {
echo "this is the output"
return 1
}
"$@"
当我 运行 main_script 输出是:
A other result (1) -> this is the output <- end
B zero result (0) -> this is the output <- end
为什么在命令替换的同一行声明局部变量会影响结果?这可能是一个错误还是我遗漏了什么?
原因是 func_b
中的 $?
反映了 local
内置命令的成功,而不是命令替换的成功 ($(...)
).
如果赋值语法正确,local
内置函数成功,无论是否有任何命令RHS 上的替换失败 或失败。
请注意,这类似于 declare
和 export
内置函数。
用一个简单的例子来说明:
declare output="$(false)"; echo $? # -> 0(!) - even though `false` obviously fails.
相比之下,如果不涉及内置函数 - 在简单变量赋值的情况下 - 命令替代失败 是 反映在 $?
:
output="$(false)"; echo $? # -> 1(!) - simple assignment; $(...) exit code is reported
这种 反直觉的行为差异是由于 local
/ declare
/ export
是 builtins 而不是 shell 语法的一部分 .
作为 builtins(内置命令),它们被视为 命令,并且命令应该通过它们的 自己的 success/failure 发出信号 退出代码;对于所述内置函数,如前所述,语法上正确的赋值被认为是成功的——换句话说:如果可以赋值 something——即使由于失败,某些东西是空字符串RHS 上的命令替换 - 内置成功。
此示例已在 Mac El Capitan 上使用 bash
进行了测试main_script.sh:
NOTE: func_a and func_b are identical except for the line that the local variable
output
is declared.
func_a () {
local output
output="$(./external.sh some_function)"
if [ $? -eq 0 ];then
echo "A zero result ($?) -> $output <- end"
else
echo "A other result ($?) -> $output <- end"
fi
}
func_b () {
local output="$(./external.sh some_function)"
if [ $? -eq 0 ];then
echo "B zero result ($?) -> $output <- end"
else
echo "B other result ($?) -> $output <- end"
fi
}
func_a
func_b
external.sh:
some_function () {
echo "this is the output"
return 1
}
"$@"
当我 运行 main_script 输出是:
A other result (1) -> this is the output <- end
B zero result (0) -> this is the output <- end
为什么在命令替换的同一行声明局部变量会影响结果?这可能是一个错误还是我遗漏了什么?
原因是 func_b
中的 $?
反映了 local
内置命令的成功,而不是命令替换的成功 ($(...)
).
如果赋值语法正确,local
内置函数成功,无论是否有任何命令RHS 上的替换失败 或失败。
请注意,这类似于 declare
和 export
内置函数。
用一个简单的例子来说明:
declare output="$(false)"; echo $? # -> 0(!) - even though `false` obviously fails.
相比之下,如果不涉及内置函数 - 在简单变量赋值的情况下 - 命令替代失败 是 反映在 $?
:
output="$(false)"; echo $? # -> 1(!) - simple assignment; $(...) exit code is reported
这种 反直觉的行为差异是由于 local
/ declare
/ export
是 builtins 而不是 shell 语法的一部分 .
作为 builtins(内置命令),它们被视为 命令,并且命令应该通过它们的 自己的 success/failure 发出信号 退出代码;对于所述内置函数,如前所述,语法上正确的赋值被认为是成功的——换句话说:如果可以赋值 something——即使由于失败,某些东西是空字符串RHS 上的命令替换 - 内置成功。