我发现了我的奇怪行为,我无法解释。 以下代码可以正常工作:
function prepare-archive {
blah-blah-blah...
_SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
exit $?
blah-blah-blah...
}
意味着我得到了我期望的价值:
bash -x ./this-script.sh:
++ exit 1
+ _SPEC_FILE='/home/likern/Print/Oleg/print-service/packaging/print-service.spec
/home/likern/Print/Oleg/print-service/packaging/print-service2.spec'
+ exit 1
只要我将local
定义添加到变量:
local _SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
我得到以下信息:
bash -x ./this-script.sh:
++ exit 1
+ local '_SPEC_FILE=/home/likern/Print/Oleg/print-service/packaging/print-service.spec
/home/likern/Print/Oleg/print-service/packaging/print-service2.spec'
+ exit 0
$:~/MyScripts$ echo $?
0
问题:为什么?发生了什么事?我可以从subshell捕获输出到local
变量并可靠地检查subshell的返回值吗?
P.S。:prepare-archive
在主shell脚本中调用。第一个exit
是来自exit
函数的check-spec-file
,第二个来自prepare-archive
函数 - 此函数本身是从主shell脚本执行的。我将check-spec-file
的值从exit 1
返回,然后将此值传递给exit $?
。因此我希望它们应该是一样的。
答案 0 :(得分:14)
要捕获子shell的退出状态,请在赋值前将变量声明为local,例如,以下脚本
#!/bin/sh
local_test()
{
local local_var
local_var=$(echo "hello from subshell"; exit 1)
echo "subshell exited with $?"
echo "local_var=$local_var"
}
echo "before invocation local_var=$local_var in global scope"
local_test
echo "after invocation local_var=$local_var in global scope"
产生以下输出
before invocation local_var= in global scope
subshell exited with 1
local_var=hello from subshell
after invocation local_var= in global scope
答案 1 :(得分:5)
在bash手册中,Shell Builtin Commands
部分:
local:
[...]The return status is zero unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.
希望这有助于=)
答案 2 :(得分:0)
当我使用bash subshell括号对许多回显命令进行分组时,遇到了这个奇怪的问题。 就我而言,我所需要的只是将一个值传递回调用外壳程序,因此我只使用了退出命令
RET=0
echo RET: $RET
(echo hello
echo there
RET=123
echo RET: $RET
exit $RET)
RET=$?
echo RET: $RET
给出以下输出
RET: 0
hello
there
RET: 123
RET: 123
没有退出命令,您将得到以下令人困惑的信息:
RET: 0
hello
there
RET: 123
RET: 0