8

我发现了我无法解释的奇怪行为。以下代码可以正常工作:

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

问:为什么?发生了什么?我可以将 subshel​​l 的输出捕获到local变量并可靠地检查 subshel​​l 的返回值吗?

PS :prepare-archive在主 shell 脚本中调用。第一个exitexitfromcheck-spec-file函数,第二个是 fromprepare-archive函数——这个函数本身是从主 shell 脚本执行的。check-spec-file我从by返回值exit 1,然后将此值传递给exit $?. 因此,我希望它们应该是相同的。

4

3 回答 3

19

要捕获 subshel​​l 的退出状态,请在赋值前将变量声明为 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
于 2013-05-11T19:56:12.190 回答
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. 

希望这会有所帮助=)

于 2012-10-11T13:49:03.023 回答
0

当我使用 bash 子shell 括号对许多 echo 命令进行分组时,我遇到了这个奇怪的问题。在我的情况下,我需要的只是将一个值传递回调用 shell,所以我只使用了 exit 命令

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

如果没有 exit 命令,您将得到令人困惑的信息:

RET: 0
hello
there
RET: 123
RET: 0
于 2019-12-20T16:44:21.203 回答