2016-03-04 3 views
7

У меня есть простой скрипт:Как ловушка ERR при использовании «набор -e» в Bash

#!/bin/bash 
set -e 
trap "echo BOO!" ERR 

function func(){ 
    ls /root/ 
} 

func 

Я хотел бы ловушкой ERR, если мой сценарий не удается (как это будет здесь б/с я не имеют разрешения на просмотр в/root). Однако при использовании set -e он не попадает в ловушку. Без set -e ERR в ловушке.

Согласно странице человека Баш, для set -e:

... Ловушка на ERR, если он установлен, выполняется перед выходом из оболочки. ...

Почему моя ловушка не выполнена? С man-страницы это похоже на то, что нужно.

+0

В стороне: лучше использовать _single-quote_ своих обработчиков ловушек, если вы явно не хотите, чтобы в нем были добавлены переменные ссылки расширенные _up front_. – mklement0

ответ

11

chepner's answer является лучшим решением: Если вы хотите объединить set -e (так же, как: set -o errexit) с a ERR ловушка, также использовать set -o errtrace (такие же как: set -E).

Короче говоря: использовать set -eE вместо того, чтобы просто set -e:

#!/bin/bash 

set -eE # same as: `set -o errexit -o errtrace` 
trap "echo BOO!" ERR 

function func(){ 
    ls /root/ 
} 

func 

man bash говорит о set -o errtrace/set -E:

Если установлено, любая ловушка на ERR наследуется функции оболочки, подстановки команд и команды, выполняемые в среде подсетей. В таких случаях ловушка ERR обычно не наследуется.

То, что я считаю, что происходит:

  • Без-e: Команда ls терпит неудачу внутри вашей функции, и, из-за того последней команды в функции, функция сообщает ls «ю.ш. ненулевой код выхода для вызывающего, область действия верхнего уровня. В , что область, ловушка ERR действует, и она вызывается (но обратите внимание, что выполнение будет продолжаться, если вы явно не вызываете exit из ловушки).

  • С-e (но без -E): Команда ls терпит неудачу внутри функции, и потому set -e действует, Bash мгновенно выходы, непосредственно из области видимости функции - и так есть нет ERR ловушка в действии там (поскольку он не был унаследован от родительской области), ваша ловушка не вызывается.

Хотя man страница не неправильно, я согласен, что такое поведение не совсем очевидно - вы должны вывести его.

3

Замените ERR на EXIT и он будет работать.

Синтаксис команды trap является: trap [COMMANDS] [SIGNALS]

Для получения дополнительной информации, пожалуйста, прочитайте http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html

+0

Так неправильная страница пользователя? –

+3

Хотя это жизнеспособное обходное решение (хотя и не нужно, если используется 'set -o errtrace'), вы должны упомянуть, что' EXIT' также вызывается в случае завершения _successful_, поэтому вам нужно добавить условное выражение как 'if [[$? -ne 0]] ... 'обработчику. – mklement0

3

Для функции наследования ловушки вам необходимо использовать set -o errtrace.

Смежные вопросы