Подтвердить что ты не робот

Bash получить статус выхода команды при включенном 'set -e'?

Обычно у меня -e установлен в моих сценариях Bash, но иногда я хотел бы запустить команду и получить возвращаемое значение.

Без танца set +e; some-command; res=$?; set -e, как я могу это сделать?

4b9b3361

Ответ 1

В руководстве bash:

Оболочка не выходит, если команда, которая не работает, является [...] частью любой команды, выполненной в && или || list [...].

Итак, просто выполните:

#!/bin/bash

set -eu

foo() {
  # exit code will be 0, 1, or 2
  return $(( RANDOM % 3 ))
}

ret=0
foo || ret=$?
echo "foo() exited with: $ret"

Пример выполнения:

$ ./foo.sh
foo() exited with: 1
$ ./foo.sh
foo() exited with: 0
$ ./foo.sh
foo() exited with: 2

Это канонический способ сделать это.

Ответ 2

в качестве альтернативы

ans=0
some-command || ans=$?

Ответ 3

Возможно, попробуйте запустить соответствующие команды в подоболочке, например?

res=$(some-command > /dev/null; echo $?)

Ответ 4

Используйте функцию обертки для выполнения ваших команд:

function __e {
    set +e
    "[email protected]"
    __r=$?
    set -e
}

__e yourcommand arg1 arg2

И используйте $__r вместо $?:

if [[ __r -eq 0 ]]; then
    echo "success"
else
    echo "failed"
fi

Другой метод вызова команд в трубе, только чтобы вы процитировали этот канал. Это делает безопасную оценку.

function __p {
    set +e
    local __A=() __I
    for (( __I = 1; __I <= $#; ++__I )); do
        if [[ "${!__I}" == '|' ]]; then
            __A+=('|')
        else
            __A+=("\"\$$__I\"")
        fi
    done
    eval "${__A[@]}"
    __r=$?
    set -e
}

Пример:

__p echo abc '|' grep abc

И я действительно предпочитаю этот синтаксис:

__p echo abc :: grep abc

Что я могу сделать с

...
        if [[ ${!__I} == '::' ]]; then
...