В то время как справочная страница Bash гласит:
Ловушка ERR не выполняется, если неудачная команда является ... частью команды, выполняемой в && или || список ...
Я надеялся, что код в подоболочке будет в другом контексте и не будет подпадать под вышеуказанное ограничение. Код ниже показывает, что даже подоболочки не застрахованы от этого ограничения:
#!/bin/bash
main()
{
local Arg="$1"
(
set -e
echo "In main: $Arg"
trap MyTrap ERR
$(exit 1)
echo "Should not get here"
)
return 1
}
MyTrap()
{
echo "In MyTrap"
}
main 1
[[ $? -eq 0 ]] || echo "failed"
echo
main 2 || echo "failed"
Приведенный выше код имеет следующий вывод:
In main: 1
In MyTrap
failed
In main: 2
Should not get here
failed
Мой нынешний обходной путь — использовать сохраняемость файлов для сохранения состояний ошибок в MyTrap
, а затем проверять коды возврата обратно в вызывающем объекте. Например:
MyTrap()
{
echo "_ERROR_=$?" > $HOME/.persist
echo "In MyTrap"
}
main 1
[[ -f $HOME/.persist ]] && . $HOME/.persist || _ERROR_=0
[[ $_ERROR_ -eq 0 ]] || echo "failed"
Вывод вышеизложенного теперь:
In main: 1
In MyTrap
failed
Итак, возникает вопрос: Можно ли найти более простой подход к перехвату подоболочки set -e/ERR, невосприимчивый к ограничениям &&
и ||
, чем описанный выше обходной путь?
Примечания. Этот вопрос касается:
- Баш 4.2 и выше
- Red Hat 7, CentOS 7 и родственные дистрибутивы (то есть не Debian и т. д.)
- Никакое стороннее программное обеспечение не должно использоваться. Пакеты должны быть доступны, например, через пакеты OS-провайдера в iso-репозитории [CentOS-7-x86_64-DVD-1611.iso][2] (аналогично для RHEL 7, Fedora 7 и т. д.).
set -e
? - person gniourf_gniourf   schedule 23.01.2017ERR
сset -e
. Это экономит мне огромное количество работы и делает код более удобным для сопровождения. Спасибо за комментарий. - person Steve Amerige   schedule 23.01.2017set -e
поведение сильно различается между разными версиями оболочки и разными конфигурациями среды выполнения; ваш код может выглядеть чище, но это не означает, что он ведет себя последовательным и предсказуемым образом, что, я бы сказал, более важно для удобства сопровождения, чем лаконичность. Если вы еще не просмотрели его, см. BashFAQ #105. - person Charles Duffy   schedule 02.02.2017set -e
- очень спорная функция в сообществе bash, и значительная часть седых волос считает, что от нее больше проблем, чем пользы; и (2) для людей из этого набора больше встроенных тестов на самом деле является предлагаемой альтернативой. Откровенно говоря, это мнение разделяют даже разработчики некоторых современных языков — см., например, подход Golang к явной обработке ошибок. - person Charles Duffy   schedule 02.02.2017set -e
и, таким образом, предостережения, которые вы можете найти в различных исторических выпусках оболочки. Если вам нужна совместимость между платформами, здесь еще будут драконы. - person Charles Duffy   schedule 02.02.2017