bash 从子shell返回值并输出到局部变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12840740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:31:17  来源:igfitidea点击:

return value from subshell and output to local variables

bashexit-codebash-function

提问by Mephi_stofel

I've found the strange behaviour for me, which I can't explain. The following code is work OK:

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

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

means I get value which I expect:

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

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

As soon as I add localdefinition to variable:

一旦我local向变量添加定义:

local _SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")

I get following:

我得到以下信息:

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

Question:Why? What has happened? Can I catch output from subshell to localvariable and check subshell's return value reliably?

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

P.S.: prepare-archiveis called in the main shell script. The first exitis the exitfrom check-spec-filefunction, the second from prepare-archivefunction - this function itself is executed from main shell script. I return value from check-spec-fileby exit 1, then pass this value to exit $?. Thus I expect they should be the same.

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

采纳答案by Janito Vaqueiro Ferreira Filho

From the bash manual, Shell Builtin Commandssection:

从 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. 

Hope this helps =)

希望这有帮助 =)

回答by vilpan

To capture subshell's exit status, declare the variable as local before the assignment, for example, the following script

要捕获子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"

produces the following output

产生以下输出

before invocation local_var= in global scope
subshell exited with 1
local_var=hello from subshell
after invocation local_var= in global scope

回答by paul.da.programmer

As I use bash subshell parenthesis to group many echo commands I hit this strange problem. In my case all I needed was to pass one value back to the calling shell so I just used the exit command

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

RET=0
echo RET: $RET
(echo hello
echo there
RET=123
echo RET: $RET
exit $RET)
RET=$?
echo RET: $RET

gives the following output

给出以下输出

RET: 0
hello
there
RET: 123
RET: 123

without the exit command you will get this which is confusing:

如果没有退出命令,你会得到这个令人困惑的:

RET: 0
hello
there
RET: 123
RET: 0