Заставьте 'ERP-ловушку' работать внутри bash функций с помощью 'return' (или в любой подоболочке) - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь использовать ловушку ERR в моих сценариях. Но:

function hmmm() {
    trap 'exit 10' ERR
    echo 12>/SOME/NONEXISTING/FILE
    # some commands that must not be done if previous has failed
    echo "THAT MUST NOT BE PRINTED" >&2
    return 5
}   

echo ok1
a=$(hmmm) || status="$?"
echo "function returns: $status"

Печать

ok1
test2.sh: line 3: /SOME/NONEXISTING/FILE: No such file or directory
THAT MUST NOT BE PRINTED
function returns: 5 

То же поведение с любой комбинацией set -e, set -E, trap на верхнем уровне et c. Мне всегда нужно обрабатывать код возврата функции - так что, как я понимаю, я вообще не могу использовать ERR-прерывание в моих скриптах - я никогда не буду работать. Я прав, или есть рабочий метод, позволяющий перехватывать ERR внутри функций, подоболочек и исходных библиотек и поддерживать конструкции типа

a=$( ...somecode ... ) || result="$?"

работающими? Или, что более важно, в приведенном выше примере сделать bash выход при ошибке внутри функции ВСЕГДА, независимо от вызова метода.

Добавлено: На самом деле, я хочу знать, есть ли рабочий способ УБЕДИТЬСЯ, что ошибки улавливаются внутри функций, подоболочек и исходного кода. Поскольку мои функции и библиотеки могут использоваться другими людьми - поэтому я не могу контролировать, как эти функции вызываются, и, если честно, даже если я могу - я никогда не буду использовать некоторое поведение внутри функции, которое может быть случайным и бесшумно изменился снаружи.

1 Ответ

0 голосов
/ 18 апреля 2020

trap не выполняется, так как является частью ||.

Изменение:

a=$(hmmm) || status="$?"

на:

a=$(hmmm)
status="$?"

С bash manual :

Ловушка ERR не выполняется, если сбойная команда является частью списка команд, который следует сразу после ключевого слова некоторое время или до, часть теста в операторе if часть команды, выполненная в && или || список, за исключением команды, следующей за последним символом && или ||, любой команды в конвейере, кроме последней, или если возвращаемое значение команды инвертируется с помощью!. Это те же самые условия, которым подчиняется опция errexit (-e).

...