Ответ 1
Я думаю, вы можете использовать $?
для получения кода выхода.
В моем коде bash есть много точек выхода. Мне нужно выполнить некоторую очистку работы при выходе, поэтому я использовал ловушку, чтобы добавить обратный вызов для выхода следующим образом:
trap "mycleanup" EXIT
Проблема в том, что существуют разные коды выхода, мне нужно выполнить соответствующие работы по очистке. Могу ли я получить код выхода в mycleanup?
Я думаю, вы можете использовать $?
для получения кода выхода.
Принятый ответ в основном правильный, я просто хочу прояснить ситуацию.
Следующий пример хорошо работает:
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...
Но вы должны быть более осторожны, если выполняете очистку inline, без функции. Например, это не сработает:
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 и знать о таких проблемах.
Я нашел, что лучше отделить ловушку EXIT от ловушки для других сигналов
Пример теста ловушки script...
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
В принципе, до тех пор, пока вы не используете "exit" в ловушке EXIT, он выйдет с сохраненным исходным значением.
ASIDE: Обратите внимание на цитирование в ловушке EXIT. Это позволяет мне изменить, какой файл нужно очистить во время жизни скриптов. Я часто также включаю тест для существования переменных $tmpfile, поэтому мне даже не нужно устанавливать его в начале script.