В сценарии Bash, как я могу выйти из всего сценария, если возникает определенное условие?
Я пишу сценарий в Bash, чтобы проверить некоторый код. Однако кажется глупым запускать тесты, Если компиляция кода не выполняется в первую очередь, и в этом случае я просто прерву тесты.
есть ли способ сделать это без обертывания всего сценария внутри цикла while и использования перерывов? Что-то вроде Дун Дун Дун Гото?
6 ответов:
попробуйте это заявление:
exit 1
заменить
1
с соответствующими кодами ошибок. Смотрите также Коды Завершения, Имеющие Предопределенный Смысл.
использовать set-e
#!/bin/bash set -e /bin/command-that-fails /bin/command-that-fails2
скрипт завершится после первой строки, которая завершится неудачно (возвращает ненулевой код выхода). В этом случае command-that-fails2 не будет работать.
если бы вы проверяли состояние возврата каждой отдельной команды, ваш скрипт выглядел бы так:
#!/bin/bash # I'm assuming you're using make cd /project-dir make if [[ $? -ne 0 ]] ; then exit 1 fi cd /project-dir2 make if [[ $? -ne 0 ]] ; then exit 1 fi
С set-e это будет выглядеть так:
#!/bin/bash set -e cd /project-dir make cd /project-dir2 make
любая команда, которая терпит неудачу, приведет к сбою всего сценария и верните статус выхода, который вы можете проверить с помощью $?. Если ваш скрипт очень длинный или вы создаете много вещей, это будет довольно уродливо, если вы добавите проверки состояния возврата везде.
один мерзкий Сисоп однажды научил меня технике трехпалого Когтя:
yell() { echo ": $*" >&2; } die() { yell "$*"; exit 111; } try() { "$@" || die "cannot $*"; }
эти функции * ОС Никс и вкус раковины-крепкий. Поставил их в начале вашего скрипта (bash или иначе),
try()
ваш оператор и код ВКЛ.объяснение
(исходя из летающих овец комментарий).
yell
: выведите имя скрипта и все аргументы вstderr
:
- это путь к скрипту ;
$*
все аргументы.>&2
означает>
перенаправить stdout в & pipe2
. труба1
будетstdout
сам по себе.die
делает то же самое, что иyell
, но выходит с не-0 статус выхода, что означает "потерпеть неудачу".try
использует||
(булевоOR
), который оценивает только правую сторону, если левая не подвел.
$@
это все аргументы снова, но разные.надеюсь, что это все объясняет.
если вы вызовете скрипт с
source
, вы можете использоватьreturn <x>
здесь<x>
будет состояние выхода скрипта (используйте ненулевое значение для error или false). Это также будет работать, как ожидалось, когда выsource
сценарий. Если вы вызываете исполняемый сценарий (т. е. непосредственно с его именем файла), оператор return приведет к жалобе (сообщение об ошибке "return: может только"return" из функции или исходного сценария").если
exit <x>
используется вместо этого, когда вызывается скрипт сsource
, это приведет к выходу из оболочки, которая запустила скрипт, но исполняемый скрипт будет работать непосредственно нормально.для обработки любого случая в том же скрипте, вы можете использовать
return <x> 2> /dev/null || exit <x>
это будет обрабатывать любой вызов может быть подходящим.
Примечание:
<x>
- это должно быть просто число.
Я часто включаю функцию run () для обработки ошибок. Каждый вызов, который я хочу сделать, передается этой функции, поэтому весь скрипт завершается при сбое. Преимущество этого по сравнению с решением set-e заключается в том, что скрипт не выходит беззвучно при сбое строки и может рассказать вам, в чем проблема. В следующем примере 3-я строка не выполняется, потому что сценарий завершается при вызове false.
function run() { cmd_output=$(eval ) return_value=$? if [ $return_value != 0 ]; then echo "Command failed" exit -1 else echo "output: $cmd_output" echo "Command succeeded." fi return $return_value } run "date" run "false" run "date"
вместо
if
построить, Вы можете использовать оценка короткого замыкания:#!/usr/bin/env bash echo $[1+1] echo $[2/0] # division by 0 but execution of script proceeds echo $[3+1] (echo $[4/0]) || exit $? # script halted with code 1 returned from `echo` echo $[5+1]
обратите внимание на пару скобок, которая необходима из-за приоритета оператора чередования.
$?
- это переменная недавно выход из кода команды.