Я писал некоторую оболочку script, и я бы счел ее полезной, если бы была возможность остановить выполнение указанной оболочки script, если какая-либо из команд не удалась. Ниже приведен пример:
#!/bin/bash
cd some_dir
./configure --some-flags
make
make install
Таким образом, в этом случае, если script не может измениться в указанную директорию, тогда он, конечно, не захочет делать. /configure после этого.
Теперь я хорошо знаю, что у меня могла бы быть проверка if для каждой команды (которая, по моему мнению, является безнадежным решением), но существует ли глобальная настройка для выхода script, если одна из команд выходит из строя?
Используйте set -e
builtin:
#!/bin/bash
set -e
# Any subsequent(*) commands which fail will cause the shell script to exit immediately
В качестве альтернативы вы можете передать -e
в командной строке:
bash -e my_script.sh
Вы также можете отключить это поведение с помощью set +e
.
(*) Примечание:
Сбой не завершается, если команда, которая не работает, является частью список команд сразу после ключевого слова в то время как или дочасть теста после if или elif зарезервированных слов, часть любой команды, выполненной в списке && или ||, за исключением команды после окончательной & или ||, любая команда в конвейере, но последнее, или если возвращаемое значение команды инвертируется с
(от man bash
)
Чтобы выйти из script, как только одна из команд не удалась, добавьте это в начале:
set -e
Это приводит к тому, что script выходит немедленно, когда некоторая команда, которая не является частью какого-либо теста (например, в if [ ... ]
или конструкторе &&
), выходит с ненулевым кодом выхода.
Вот как это сделать:
#!/bin/sh
abort()
{
echo >&2 '
***************
*** ABORTED ***
***************
'
echo "An error occurred. Exiting..." >&2
exit 1
}
trap 'abort' 0
set -e
# Add your script below....
# If an error occurs, the abort() function will be called.
#----------------------------------------------------------
# ===> Your script goes here
# Done!
trap : 0
echo >&2 '
************
*** DONE ***
************
'
EXIT
, ловушка IOW при выходе
Я думаю, что вы ищете команду trap
:
trap command signal [signal ...]
Для получения дополнительной информации см. эту страницу.
Другим вариантом является использование команды set -e
в верхней части вашего script - это приведет к завершению script, если какая-либо программа/команда вернет неверное значение.
Одна идиома:
cd some_dir && ./configure --some-flags && make && make install
Я понимаю, что это может затянуться, но для больших скриптов вы можете разбить его на логические функции.
&&
для удобства чтения
В случае, если script вызывает индекс внутри, опция pipefail
может быть полезна.
set -e
set -o pipefail
-e (errexit): Abort script при первой ошибке, когда команда выходит с ненулевым статусом (за исключением циклов while или while, if-tests, list)
-o pipefail: Заставляет конвейер возвращать статус завершения последней команды в канале, который возвратил ненулевое возвращаемое значение.
Альтернатива принятому ответу, который подходит в первой строке:
#!/bin/bash -e
cd some_dir
./configure --some-flags
make
make install
sh
так же, как кbash
?