LINUX.ORG.RU

«set -e»-корректные функции-обёртки в bash

 


0

2

Предположим, что у нас есть функция-обёртка, которая последним действием вызывает нечто другое и хочет вернуть его (этого чего-то) exit code. Например, вот так:

function pkgbuild_is_devel() {
    local NAME="$1"
    [[ "$NAME" =~ -(svn|cvs|git|hg)$ ]]
}

Проблема в том, что при выполнении скрипта с set -e («Exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command, exits with a non-zero status») так не напишешь: последняя строка совершенно правомерно валит скрипт. Приходится писать так:

function pkgbuild_is_devel() {
    local NAME="$1"
    if [[ "$NAME" =~ -(svn|cvs|git|hg)$ ]]; then
        return 0
    else
        return 1
    fi
}

Так работает, потому что команды-условия исключаются из этой проверки. Но это слишком громоздко. Отсюда вопрос: каким образом это можно сделать компактнее? Отключить set -e не предлагать.

(Я надеюсь, что на ЛОРе есть хотя бы один человек, которому вообще не пофиг на обработку ошибок в скриптах: судя по инит-срачам, все местные скриптолюбители всегда пишут едва ли не идеальный код.)

★★★★★

Ответ на: комментарий от mironov_ivan

А разница? Скрипт свалится на [[ ]], потому что это compound command.

$ ( set -e; function f() { [[ a == b ]]; return $?; }; f; echo alive )

$
intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 4)
Ответ на: комментарий от intelfx

Вообще ты что-то делаешь не так.

$ set -e

$ fn() { false; return $?; }

$ fn || echo false
false

$ fn() { false; }

$ fn || echo false
false
Работает хоть как.

mironov_ivan ★★★★★ ()
Ответ на: комментарий от mironov_ivan

The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

mironov_ivan

Нет, ты всё правильно написал. Я идиот.

Действительно, если функция-обёртка, для которой ненулевой код возврата — штатная ситуация, вызывается в контексте любой проверки (а она будет вызываться именно так), set -e в любом случае игнорируется.

Спасибо %)

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 2)

[[ «$NAME» =~ -(svn|cvs|git|hg)$ ]] && return 0 || return 1

Deleted ()
Ответ на: комментарий от Deleted

Как вариант. Но мы тут уже выяснили, что я идиот, и в ОП изложены бессмысленные требования.

intelfx ★★★★★ ()
pkgbuild_is_devel () {
    local NAME="${1}"
    [[ "${NAME}" =~ -(svn|cvs|git|hg)$ ]] && :
}
ABW ★★★★ ()
Ответ на: комментарий от intelfx

Это пока тебе не захочется написать чего-либо вроде

f3 () {
  if [ "${1}" = 'a' ]
  then f1 "${2}"
  else f2 "${2}"
  fi
}
или нарисовать функцию с недвоичным кодом возврата.

ABW ★★★★ ()
Ответ на: комментарий от ABW

пока тебе не захочется написать чего-либо вроде f3 ...

В этом случае (если f3 будет вызываться внутри if/elif/while/until) всё тоже хорошо, set -e будет игнорироваться.

или нарисовать функцию с недвоичным кодом возврата

Гм. Да, тут && : действительно пригодится. Опять же, спасибо.

intelfx ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.