Если я использую, trap
как описано, например, на http://linuxcommand.org/wss0160.php#trap, чтобы перехватить ctrl-c (или подобный) и выполнить очистку перед выходом, то я изменяю возвращенный код выхода.
Теперь это, вероятно, не будет иметь значения в реальном мире (например, потому что коды выхода не являются переносимыми и вдобавок к этому не всегда однозначными, как обсуждалось в Коде выхода по умолчанию, когда процесс завершается? ), Но все же мне интересно, есть ли там неужели нет способа предотвратить это и вместо этого вернуть код ошибки по умолчанию для прерванных сценариев?
Пример (в bash, но мой вопрос не должен рассматриваться как специфичный для bash):
#!/bin/bash
trap 'echo EXIT;' EXIT
read -p 'If you ctrl-c me now my return code will be the default for SIGTERM. ' _
trap 'echo SIGINT; exit 1;' INT
read -p 'If you ctrl-c me now my return code will be 1. ' _
Вывод:
$ ./test.sh # doing ctrl-c for 1st read
If you ctrl-c me now my return code will be the default for SIGTERM.
$ echo $?
130
$ ./test.sh # doing ctrl-c for 2nd read
If you ctrl-c me now my return code will be the default for SIGTERM.
If you ctrl-c me now my return code will be 1. SIGINT
EXIT
$ echo $?
1
(Отредактировано для удаления, чтобы сделать его более соответствующим POSIX.)
(Вместо этого отредактировано снова, чтобы сделать его bash-скриптом, но мой вопрос не относится к оболочке.)
Отредактировано для использования переносного "INT" для ловушки в пользу непереносимого "SIGINT".
Отредактировано, чтобы удалить ненужные фигурные скобки и добавить потенциальное решение.
Обновить:
Я решил это сейчас, просто выйдя с жестко закодированными кодами ошибок и перехватив EXIT. Это может быть проблематично в некоторых системах, потому что код ошибки может отличаться или прерывание EXIT невозможно, но в моем случае это достаточно.
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
read -p
читает входные данные текущего процесса.
read
чтобы читать из текущего сопроцессора иtrap cmd SIGINT
не будет работать, поскольку стандарт говорит, что вы должны использоватьtrap cmd INT
.