код выхода из вызова функции игнорируется, если хранится в локальной переменной - PullRequest
2 голосов
/ 11 октября 2019

Ниже приведен пример сценария: -

Определен пример функции, которая отображает некоторый текст, а также задает код выхода с помощью return. Есть еще один скрипт, который вызывает эту функцию. Ниже приведен упрощенный код: -

~/playground/octagon/bucket/test/sample $

pwd
/Users/riteshverma/playground/octagon/bucket/test/sample

~/playground/octagon/bucket/test/sample $

cat functions.sh
myfunc() {
    echo "This is output $1"
    return 3
}

~/playground/octagon/bucket/test/sample $

cat example.sh
. functions.sh

function example(){
    myfunc_out=$(myfunc $1); myfunc_rc=$?
    echo "myfunc_out is: $myfunc_out"
    echo "myfunc_rc is: $myfunc_rc"
}

example $1

~/playground/octagon/bucket/test/sample $

sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 3

Теперь, если я использую local для переменных, которые используются для хранения возвращаемого значения функции и кода выхода в example.sh, то код выхода поступает неправильно. Пожалуйста, найдите ниже модифицированный пример .sh: -

~/playground/octagon/bucket/test/sample $

cat example.sh
. functions.sh

function example(){
    local myfunc_out=$(myfunc $1); local myfunc_rc=$?
    echo "myfunc_out is: $myfunc_out"
    echo "myfunc_rc is: $myfunc_rc"
}

example $1

~/playground/octagon/bucket/test/sample $

sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 0

1 Ответ

4 голосов
/ 11 октября 2019

Когда вы пишете:

var=$(cmd)

, вывод cmd присваивается var (без разделения слов), а $? устанавливается на значение, возвращаемое cmd.

Когда вы пишете:

var=$(cmd1) cmd2

cmd1 выполняется и его вывод (без разделения слов) присваивается переменной var в среде cmd2, котораязатем выполнен. $? устанавливается на значение, возвращаемое cmd2.

Когда вы пишете:

cmd1 var=$(cmd2)

cmd2, строка var=output of cmd2 подвергается разбиению по словам и передается как аргумент (ы) cmd1, а $? устанавливается на значение, возвращаемое cmd1. (Почти во всех случаях вы хотите подавить разделение слов и вместо этого написать cmd1 var="$(cmd2)", что гарантирует передачу только одного аргумента.)

local - это команда, а local myfunc_out=$(myfunc $1) - это3-я форма (с предупреждением), поэтому она устанавливает $? на значение, возвращаемое local. Обратите внимание, что если выходные данные myfunc $1 содержат пробелы, разделение слов происходит , а не . Процитируем man-страницу: Assignment statements may also appear as arguments to the alias, declare, typeset, export, readonly, and local builtin commands, так что строка считается присвоением переменной, а разделение слов не выполняется.

Короче говоря, local имеет выходное значение и используется для установки $?

Вместо назначения присваивания аргумента для local, вы можете использовать:

local myfunc_out myfunc_rc
myfunc_out="$(myfunc $1)"; myfunc_rc=$?

Обратите внимание, что двойные кавычки здесь не являются строго необходимыми, поскольку разделение слов не происходитв задании, но их использование, безусловно, является хорошей практикой.

...