Как ловить код выхода в скрипте Bash
Вопрос
В моем коде Bash есть много точек выхода. Мне нужно сделать несколько работ по выходу, поэтому я использовал ловушку, чтобы добавить обратный вызов для выхода, как это:
trap "mycleanup" EXIT
Проблема в том, что существуют разные коды выхода, мне нужно выполнять соответствующие работы по очистке. Могу ли я получить код выхода в MyCleanup?
Решение
Я думаю, ты можешь использовать $?
Чтобы получить код выхода.
Другие советы
Принятый ответ в основном правильный, я просто хочу прояснить вещи.
Следующий пример работает хорошо:
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...
Но вы должны быть более осторожны, если вы выполняете встроенную очистку, без функции. Например, это не сработает:
trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT
Вместо этого вы должны избежать $rv
а также $?
переменные:
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
Вы также можете сбежать $tmpdir
, как это будет оцениваться, когда строка ловушки будет выполнена и если tmpdir
Изменения в стоимости позже это не даст вам ожидаемого поведения.
РЕДАКТИРОВАТЬ: Используйте Shellcheck Чтобы проверить свои сценарии Bash и знать о таких проблемах.
Я обнаружил, что лучше отделить ловушку для выхода от ловушки для других сигналов
Пример тестирования ловушки ...
umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM
touch $tmpfile
read -r input
exit 10
Временный файл очищается. Значение выхода файла 10 сохранилось! Прерывания приводят к выходу 2
По сути, если вы не используете «выход» в выходящей ловушке, он выйдет с исходным значением выхода.
В стороне: обратите внимание на цитату в ловушке выхода. Это позволяет мне изменить, какой файл должен быть очищен в течение жизни сценариев. Я также часто включаю тест на существование $ tmpfile, прежде чем пытаться его удалить, поэтому мне даже не нужно устанавливать его в начале сценария, только перед его созданием.