Выполнение (exit 1);
- это самый простой способ вызвать ERR
ловушку. Это также вызовет немедленный выход, если set -e
он действует. (Для запуска условия ошибки требуется команда для сбоя; exit
при значении ошибки в подоболочке происходит сбой подоболочки.)
exit 1;
не будет делать ни одной из этих вещей.
Таким образом, {(exit 1); exit 1;}
можно использовать сначала для создания ERR
ловушки, которая может сделать что-то полезное для целей отладки, а затем завершить сценарий с указанием ошибки.
Но это не то, что происходит в autoconf
файлах. autoconf
сценарии полагаются на EXIT
ловушку для очистки временных файлов, созданных во время выполнения. Большинство оболочек, в том числе bash
, устанавливают статус из значения, указанного в exit
команде, перед вызовом EXIT
прерывания. Это может позволить EXIT
ловушке определить, была ли она вызвана из-за ошибки или нормального завершения, и это также позволяет ей убедиться, что состояние выхода правильно установлено в конце операции прерывания.
Однако, по-видимому, некоторые снаряды не взаимодействуют. Вот цитата из autoconf
руководства :
Некоторые сценарии оболочки, например, созданные сценариями, autoconf
используют ловушку для очистки перед выходом. Если последняя команда оболочки вышла с ненулевым статусом, ловушка также выходит с ненулевым статусом, чтобы вызывающий мог сказать, что произошла ошибка.
К сожалению, в некоторых оболочках, таких как Solaris /bin/sh
, ловушка выхода игнорирует аргумент команды выхода. В этих оболочках ловушка не может определить, была ли она вызвана простым выходом или выходом 1. Вместо прямого вызова выхода используйте AC_MSG_ERROR
макрос, который имеет обходной путь для этой проблемы.
Обходной путь должен убедиться, что он $?
имеет статус выхода перед выполнением exit
команды, так что он определенно будет иметь это значение при выполнении EXIT
ловушки. И действительно, это AC_MSG_ERROR
макрос, который вставляет этот любопытный код, дополненный избыточными скобками.
false
вместо(exit 1)
?