Как выйти, если команда не удалась?
Я новичок в shell-скриптов. Я хочу распечатать сообщение и выйти из моего сценария, если команда не выполняется. Я пробовал:
my_command && (echo 'my_command failed; exit)
но это не работает. Он продолжает выполнять инструкции, следующие за этой строкой в скрипте. Я использую Ubuntu и bash.
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