Вернуть значение из subshell и вывести на локальные переменные

Я обнаружил странное для меня поведение, которое не могу объяснить. Следующий код работает нормально:

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 надежно?

PS: prepare-archive вызывается в основном сценарии оболочки. Первый exit это exit от check-spec-file функция, вторая из prepare-archive функция - сама эта функция выполняется из основного сценария оболочки. Я возвращаю значение из check-spec-file от exit 1затем передайте это значение exit $?, Таким образом, я ожидаю, что они должны быть одинаковыми.

2 ответа

Решение

Из руководства по 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. 

Надеюсь, это поможет =)

Чтобы зафиксировать состояние выхода subshell, объявите переменную как локальную перед назначением, например, следующий скрипт

#!/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

Поскольку я использую скобки подоболочки bash для группировки многих эхо-команд, я столкнулся с этой странной проблемой. В моем случае все, что мне было нужно, это передать одно значение обратно в вызывающую оболочку, поэтому я просто использовал команду выхода

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
Другие вопросы по тегам