return value from subshell and output to local variables
-
06-07-2021 - |
Question
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 local
definition to variable:
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 local
variable and check subshell's return value reliably?
P.S.: prepare-archive
is called in the main shell script. The first exit
is the exit
from check-spec-file
function, the second from prepare-archive
function - this function itself is executed from main shell script. I return value from check-spec-file
by exit 1
, then pass this value to exit $?
. Thus I expect they should be the same.
Solution
From the bash manual, Shell Builtin Commands
section:
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 =)
OTHER TIPS
To capture subshell's exit status, declare the variable as local before the assignment, for example, the following script
#!/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
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
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