Я нуб в сценариях оболочки. Я хочу напечатать сообщение и выйти из сценария, если команда не выполнена. Я пробовал:
my_command && (echo 'my_command failed; exit)
Но это не работает. Он продолжает выполнять инструкции, следующие за этой строкой в скрипте. Я использую Ubuntu и Bash.
linux
bash
exit
exitstatus
user459246
источник
источник
Ответы:
Пытаться:
Четыре изменения:
&&
на||
{ }
вместо( )
;
послеexit
и{
и до}
Так как вы хотите напечатать сообщение и выйти только в случае сбоя команды (выход с ненулевым значением), вам не нужно
||
указывать&&
.будет работать
cmd2
приcmd1
успешном завершении (выходное значение0
). В то время какбудет работать
cmd2
приcmd1
сбое (выходное значение ненулевое).Использование
( )
заставляет команду внутри них запускаться в под-оболочке, а вызовexit
оттуда приводит к выходу из под-оболочки, а не к исходной оболочке, следовательно, выполнение продолжается в исходной оболочке.Чтобы преодолеть это использование
{ }
Последние два изменения требуются bash.
источник
{ (>&2 echo 'my_command failed') ; exit 1; }
Другие ответы хорошо охватили прямой вопрос, но вы также можете быть заинтересованы в использовании
set -e
. При этом любая команда, которая не будет выполнена (вне определенного контекста, например,if
тестов), приведет к прерыванию работы скрипта. Для некоторых скриптов это очень полезно.источник
set -e
имеет длинный и загадочный набор правил о том, когда он работает, а когда нет. (Если кто-то запускаетсяif yourfunction; then ...
, тоset -e
никогда не будет запускаться внутриyourfunction
или чем-то, что он вызывает, потому что этот код считается «проверенным»). Смотрите раздел упражнений BashFAQ # 105 , обсуждая эту и другие ловушки (некоторые из которых относятся только к определенным версиям оболочки, поэтому вы должны быть уверены, что проверили каждый выпуск, который может быть использован для запуска вашего скрипта).Также обратите внимание, что состояние выхода каждой команды хранится в переменной оболочки $?, Которую вы можете проверить сразу после запуска команды. Ненулевое состояние означает сбой:
источник
echo "Just finished step A"
, не зная, что этоecho
переписало то,$?
что будет проверено позже.Если вы хотите такое поведение для всех команд в вашем скрипте, просто добавьте
в начале сценария. Эта пара опций указывает интерпретатору bash выходить всякий раз, когда команда возвращается с ненулевым кодом выхода.
Это не позволяет вам распечатать сообщение о выходе.
источник
trap
встроенную команду bash.set -o pipefail
может не быть желаемого поведения. Еще спасибо за указание на это!set -e
не совсем надежный, последовательный или предсказуемый! Чтобы убедиться в этом, просмотрите раздел упражнений BashFAQ # 105 или таблицу сравнения поведения различных оболочек на in-ulm.de/~mascheck/various/set-eЯ взломал следующую идиому:
Перед каждой командой следует информационное эхо, а за каждой командой следует та же
if [ $? -ne 0 ];...
строка. (Конечно, вы можете отредактировать это сообщение об ошибке, если хотите.)источник
if ! javac *.java; then ...
- зачем$?
вообще?При условии, что
my_command
он канонически спроектирован, то есть возвращает 0 в случае успеха, тогда&&
это полная противоположность того, что вы хотите. Вы хотите||
.Также обратите внимание, что
(
в bash мне это не кажется правильным, но я не могу попробовать оттуда, где я нахожусь. Скажи-ка.источник
Вы также можете использовать, если вы хотите сохранить статус ошибки выхода, и иметь читаемый файл с одной командой на строку:
Это, однако, не будет печатать никаких дополнительных сообщений об ошибках. Но в некоторых случаях ошибка все равно будет напечатана неудачной командой.
источник
exit $?
; простоexit
использует в$?
качестве значения по умолчанию.trap
Встроенная оболочка позволяет ловить сигналы, а также другие полезные условия, в том числе не удалось выполнения команды (т.е. статус возврата не равен нулю). Поэтому, если вы не хотите явно проверять состояние возврата каждой отдельной команды, вы можете сказать,trap "your shell code" ERR
и код оболочки будет выполняться каждый раз, когда команда возвращает ненулевой статус. Например:trap "echo script failed; exit 1" ERR
Обратите внимание, что, как и в других случаях перехвата неудачных команд, конвейеры нуждаются в особой обработке; выше не поймаешь
false | true
.источник