Подтвердить что ты не робот

Как заблокировать код выхода в Bash script

В моем коде bash есть много точек выхода. Мне нужно выполнить некоторую очистку работы при выходе, поэтому я использовал ловушку, чтобы добавить обратный вызов для выхода следующим образом:

trap "mycleanup" EXIT

Проблема в том, что существуют разные коды выхода, мне нужно выполнить соответствующие работы по очистке. Могу ли я получить код выхода в mycleanup?

4b9b3361

Ответ 1

Я думаю, вы можете использовать $? для получения кода выхода.

Ответ 2

Принятый ответ в основном правильный, я просто хочу прояснить ситуацию.

Следующий пример хорошо работает:

#!/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 и знать о таких проблемах.

Ответ 3

Я нашел, что лучше отделить ловушку 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.