Как выйти, если команда не удалась?



Я новичок в shell-скриптов. Я хочу распечатать сообщение и выйти из моего сценария, если команда не выполняется. Я пробовал:



my_command && (echo 'my_command failed; exit)


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

616   9  

9 ответов:

попробуй:

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

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

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

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

cmd1 && cmd2

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

cmd1 || cmd2

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

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

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

последние bash требует двух изменений.

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

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

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

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

  set -e 
  set -o pipefail

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

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

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

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 ];... линии. (Конечно, вы можете изменить это сообщение об ошибке, если хотите.)

при условии my_command канонически разработанных, ie возвращает 0 при успешном выполнении, затем && - это прямо противоположно тому, чего вы хотите. Ты хочешь ||.

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

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

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

trap "echo script failed; exit 1" ERR

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

на ошибок команды:

execute [INVOKING-FUNCTION] [COMMAND]

execute () {
    error=$( 2>&1 >/dev/null)

    if [ $? -ne 0 ]; then
        echo ": $error"
        exit 1
    fi
}

вдохновение в бережливом производстве:

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

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

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

Comments

    Ничего не найдено.