Как остановить скрипт bash при неудачном состоянии?

10

Здесь показано использование || и && в одной строке для конкатенации выполнения команд: Как проверить ошибки apt-get в сценарии bash?

Я пытаюсь остановить выполнение скрипта, если какое-то условие терпит неудачу,

например.

false || echo "Obvious error because its false on left" && exit

Здесь он печатает Obvious error because its false on the left и выходит из консоли, что я хотел.

true || echo "This shouldn't print" && exit

Здесь нет эхо-печати, но выполняется команда exit , т. е. консоль закрыта, не должна ли команда exit не запускаться, потому что команда эхо справа не была выполнена? Или по умолчанию заявление считается ложным в левой части оператора && ?

Изменить: Я должен был упомянуть об этом раньше, моя цель состояла в том, чтобы повторить ошибку и выйти, если это было непонятно. w.r.t к моему конкретному случаю ошибок уловов при условиях группировки с использованием & amp; & amp; и ||, @ bodhi.zazen ответ решает проблему.

@takatakatek ответ дает более четкое представление об управлении потоком, а ссылки руководства bash превосходны.

Ответ @muru имеет хорошее объяснение, почему бы не использовать set -e, если вы хотите, чтобы пользовательские сообщения об ошибках были брошены с альтернативами использования perl и trap, которые, по моему мнению, являются более надежным способом и видят, что я использую его из моего второго bash скрипт вперед!

    
задан kosol 13.06.2017 в 00:10
источник

4 ответа

10

Вероятно, вы хотите (как указано steeldriver)

true || { echo "This shouldn't print" && exit; }

В противном случае ваш скрипт читает одно условие в момент

a или b, а затем выйдите из

Я думаю, вы хотите a или (b и выйти)?

    
ответ дан Panther 13.06.2017 в 00:52
источник
13

Проблема состоит в том, что || и & amp; & amp; только пропустить одну последующую строфу цепочки команд, когда условие не выполняется. Если вы выписываете полную структуру блока, это имеет смысл. То, что вы написали, становится следующим:

if ! true ; then
   echo "This shouldn't print"
else
   exit
fi

Что вы хотите, так это:

if ! true ; then
   echo "This shouldn't print"
   exit
fi

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

ответ дан takatakatek 13.06.2017 в 01:03
7

Самый простой способ сбой при ошибке - использовать параметр -e bash ( set -e или /bin/bash -e в shebang). Однако это не упрощает отправку пользовательских сообщений об ошибках. Есть несколько идиом, которые могли бы сделать это проще:

die à la Perl

Perl имеет очень удобную команду die , которая печатает сообщение в stderr и создает исключение, которое обычно приводит к завершению сценария. Вы можете эмулировать это:

die () {
  ret=$?
  print "%s\n" "[email protected]" >&2
  exit "$ret"
}

false || die "Obvious error because its false on left"
true || die "This shouldn't print"

trap ERR

Команда trap <command> может использоваться для запуска команды при получении сигнала или при выходе из скрипта ( trap ... EXIT ) или когда команда возвращает ошибку ( trap ... ERR ). Так что-то вроде:

trap 'ret=$?; printf "%s\n" "$ERR_MSG" >&2; exit "$ret"' ERR

Тогда:

ERR_MSG="Obvious error because its false here"
false
ERR_MSG="This shouldn't print"
true

В любом случае я бы предложил использовать не менее exit 1 , чтобы указать, что сценарий не удалось . Простой exit будет использовать статус выхода предыдущей команды, который в этих случаях будет командами echo или printf , которые обычно будут успешными. Сохранение статуса выхода сбойной команды, как я сделал здесь, было бы неплохо.

    
ответ дан muru 13.06.2017 в 06:56
5

Вы можете попробовать немного поэкспериментировать с запуском скрипта с помощью

#!/bin/bash -e

Параметр -e гарантирует, что сценарий завершится, когда что-то вернет false. Затем можно избежать определенного сбоя с помощью something || true

    
ответ дан aggregate1166877 13.06.2017 в 01:22