BASH - передать статус предыдущего оператора в функцию? - PullRequest
0 голосов
/ 14 марта 2019

Как передать статус предыдущей команды функции?

Другими словами - почему эти команды работают должным образом:

$: false && echo "true" || echo "false"
>> false

$: true && echo "true" || echo "false"
>> true

Но это не так:

function status () {
    echo "true" || echo "false"
}

$: true && status
>> true

$: false && status
>>

И как бы заставить вышеуказанную функцию работать как положено?

Ответы [ 2 ]

3 голосов
/ 14 марта 2019

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

status() {
  if (( $? == 0 )); then
    echo "true"
  else
    echo "false"
  fi
}

(Это более надежно, чем a && b || c, который может запускать и b и c, если a имеет значение true, но b обнаруживает ошибку во время выполнения).


После:

$ true; status
true
$ false; status
false

Кстати, я бы лично написал это так, чтобы инвертировать управление потоком:

run_with_status() {
  local retval
  if "$@"; then
    echo "true"
  else
    retval=$?
    echo "false"
    return "$retval"
  fi
}

run_with_status true
run_with_status false

Эта форма будет лучше воспроизводиться с set -e (который в противном случае завершится при ошибках до достижения возможности печатать false) или с ERR ловушками, и позволит избежать потенциальных ошибок, когда кто-то добавит echo для ошибки непреднамеренное ведение журнала изменяет значение $?.

2 голосов
/ 14 марта 2019

Ваши исходные операторы анализируются как:

( false && echo "true" ) || echo "false"
( true && echo "true" ) || echo "false"

Это не выполняется точно так, как нет подоболочек, но это показывает, как операторы группируются.

Когда выпереместите операторы echo в функцию, это выглядит примерно так:

false && ( echo "true" || echo "false" )
true && ( echo "true" || echo "false" )

В этом случае результат false или true контролирует выполнение всей группы, а не только однойecho.

...