从subshel​​l返回值并输出到局部变量

Mep*_*fel 8 bash exit-code bash-function

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

function prepare-archive {
blah-blah-blah...
_SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
exit $?
blah-blah-blah...
}
Run Code Online (Sandbox Code Playgroud)

意味着我得到了我期望的价值:

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
Run Code Online (Sandbox Code Playgroud)

只要我local向变量添加定义:

local _SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
Run Code Online (Sandbox Code Playgroud)

我得到以下:

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
Run Code Online (Sandbox Code Playgroud)

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

PS:prepare-archive在主shell脚本中调用.第一个exitexitfrom check-spec-file函数,第二个是prepare-archive函数 - 这个函数本身是从main shell脚本执行的.我从返回值check-spec-fileexit 1,那么通过这个值exit $?.因此我希望它们应该是一样的.

vil*_*pan 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"
Run Code Online (Sandbox Code Playgroud)

产生以下输出

before invocation local_var= in global scope
subshell exited with 1
local_var=hello from subshell
after invocation local_var= in global scope
Run Code Online (Sandbox Code Playgroud)

  • @IhorKaharlichenko 如果在声明时使用`local` 分配了变量,则子shell 退出状态将被`local` 内置命令的退出状态“屏蔽”/覆盖。在赋值之前声明一个局部变量也更容易移植(一些 shell 不支持用 `local` 初始化)。 (2认同)

Jan*_*lho 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. 
Run Code Online (Sandbox Code Playgroud)

希望这有助于=)

  • @Mephi_stofel-要解决它,您可以拆分声明和初始化,例如,首先是:local my_var,然后是my_var = $(my_function)。初始化将安全地引用局部变量,而不会污染全局范围。 (2认同)