Как выйти из командной строки?

Я использую noob в shell-scripting. Я хочу напечатать сообщение и выйти из script, если команда завершилась неудачей. Я пробовал:

my_command && (echo 'my_command failed; exit)

но это не сработает. Он продолжает выполнять инструкции, следующие за этой строкой, в script. Я использую Ubuntu и bash.

Ответ 1

Try:

my_command || { echo 'my_command failed' ; exit 1; }

Четыре изменения:

  • Измените && на ||
  • Используйте { } вместо ( )
  • Введите ; после exit и
  • пробелы после { и до }

Поскольку вы хотите распечатать сообщение и выйти только тогда, когда команда выйдет из строя (выходит с ненулевым значением), вам нужно || not a &&.

cmd1 && cmd2

будет запускать cmd2, когда cmd1 будет успешно (значение выхода 0). Где

cmd1 || cmd2

будет запускать cmd2, когда cmd1 терпит неудачу (значение выхода отличное от нуля).

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

Чтобы преодолеть это использование { }

Последние два изменения требуются bash.

Ответ 2

Другие ответы хорошо затронули прямой вопрос, но вы также можете быть заинтересованы в использовании set -e. При этом любая команда, которая терпит неудачу (за пределами конкретных контекстов, таких как тесты if), приведет к прерыванию script. Для некоторых скриптов это очень полезно.

Ответ 3

Если вам нужно это поведение для всех команд в script, просто добавьте

  set -e 
  set -o pipefail

в начале script. Эта пара опций сообщает интерпретатору bash выйти, когда команда возвращается с ненулевым кодом выхода.

Это не позволяет печатать сообщение о выходе.

Ответ 4

Обратите также внимание, что каждый статус выхода команды сохраняется в переменной оболочки $?, которую вы можете проверить сразу после запуска команды. Не нулевой статус указывает на сбой:

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi

Ответ 5

Я взломал следующую идиому:

echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Done."

Предваряйте каждую команду информативным эхом и следуйте каждой команде с тем же самым   if [ $? -ne 0 ];.... (Конечно, вы можете отредактировать это сообщение об ошибке, если хотите.)

Ответ 6

Если my_command канонически спроектирован, то есть возвращает 0 при успешном завершении, тогда && точно противоположно тому, что вы хотите. Вы хотите ||.

Также обратите внимание, что ( мне не кажется правильным в bash, но я не могу попробовать, где я. Скажи мне.

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}

Ответ 7

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

my_command1 || exit $?
my_command2 || exit $?

Это, однако, не будет печатать никаких дополнительных сообщений об ошибках. Но в некоторых случаях ошибка все равно будет напечатана неудачной командой.

Ответ 8

Встроенная оболочка trap позволяет перехватывать сигналы и другие полезные условия, включая неудачное выполнение команды (т.е. ненулевой статус возврата). Поэтому, если вы не хотите явно проверять состояние возврата каждой отдельной команды, вы можете сказать trap "your shell code" ERR, и код оболочки будет выполняться каждый раз, когда команда возвращает ненулевой статус. Например:

trap "echo script failed; exit 1" ERR

Обратите внимание, что, как и в других случаях перехвата неудачных команд, конвейеры нуждаются в особой обработке; вышеупомянутое не поймает false | true.

Ответ 9

молча не только прерывает работу при сбое, но и выводит команды из строя до тех пор, пока это не произойдет. Таким образом, его правильная работа контролируется самим собой (aka jidoka)