2016-06-19 9 views
2

Этот пример был протестирован на Mac El Capitan с БашБаш подстановки команд на функцию внешнего сценария получает неверный статус выхода

main_script.sh:

Примечание: func_a и func_b идентичны, за исключением того, что линии объявляется локальная переменная output.

func_a() { 
    local output 
    output="$(./external.sh some_function)" 
    if [ $? -eq 0 ];then 
     echo "A zero result ($?) -> $output <- end" 
    else 
     echo "A other result ($?) -> $output <- end" 
    fi 
} 

func_b() { 
    local output="$(./external.sh some_function)" 
    if [ $? -eq 0 ];then 
     echo "B zero result ($?) -> $output <- end" 
    else 
     echo "B other result ($?) -> $output <- end" 
    fi 
} 

func_a 
func_b 

external.sh:

some_function() { 
    echo "this is the output" 
    return 1 
} 

"[email protected]" 

Когда я бегу main_script выход:

A other result (1) -> this is the output <- end 
B zero result (0) -> this is the output <- end 

По какой причине бы объявление локальной переменной на той же строке, что влияет на результат? Может быть, это ошибка или я что-то пропустил?

+0

Это может помочь: [Как отлаживать скрипт bash?] (Http://unix.stackexchange.com/q/155551/74329) – Cyrus

+0

Хорошо известно, как отлаживать скрипт bash и что задает -x. Я просто старался сделать вывод максимально ясным. Я знаю, в чем проблема, теперь мне интересно, почему. Кажется, объявление локального var возвращает ноль, несмотря ни на что .. Похоже на ошибку bash? – arctelix

ответ

2

Причина заключается в том, что $? в func_b отражает успех local, а не встроенной команды успеха подстановки команд ($(...)).

local успешна, если встроенная команда присваивание синтаксически правильно - независимо от того, терпит ли любая команда замещения на RHS или нет.

Обратите внимание, что это применяется аналогично встроенным контроллерам declare и export.

Чтобы проиллюстрировать на простом примере:

declare output="$(false)"; echo $? # -> 0(!) - even though `false` obviously fails. 

В противоположность этому, , если нет встроенной не участвует - в случае простого присваивания значения переменной - отказа команды подстановки в является отражение в $?:

output="$(false)"; echo $? # -> 1(!) - simple assignment; $(...) exit code is reported 

Это нелогичного различие в поведении объясняется тем, что local/declare/exportявляется встроенными функциями, а не часть синтаксиса оболочки.

Как встроенные команды (встроенные команды), они рассматриваются как команды, и команды, как ожидается, чтобы сигнализировать их успех/провал через их собственный код выхода; в случае упомянутых встроенных функций, как указано, синтаксически правильное присваивание считается успешным - другими словами: если может быть присвоено что-то - даже если это что-то является нулевой строкой из-за неудачной подстановки команды на RHS - встроенной удалось.

+0

То, что я понял, продолжалось. Сказать глупо, что объявление переменной приведет к успеху задания. Но опять же вещи редко интуитивно понятны в оболочке сценария земли .. – arctelix

+0

@arctelix: Это определенно контр-интуитивно; Я добавил некоторую справочную информацию, которая, надеюсь, объяснит, по крайней мере, почему это происходит. – mklement0

 Смежные вопросы

  • Нет связанных вопросов^_^