1

如何在 Bash 脚本中处理内部函数的返回值(可能返回非零值)而不被陷阱捕获

例如,如果perform_test 返回 1,则脚本结束,因为非零返回值被捕获并由exit_handler函数调用处理。

我该怎么做才能避免这种行为?

谢谢

这里的脚本:

#!/bin/bash

set -o pipefail  # trace ERR through pipes
set -o errtrace  # trace ERR through 'time command' and other functions
set -o nounset   ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit   ## set -e : exit the script if any statement returns a non-true return value

exit_handler(){
    #...
    echo "${error_filename}${error_lineno:+: $error_lineno}: ${error_msg}"
    exit "${error_code}"
}

trap exit_handler EXIT      # ! ! ! TRAP EXIT ! ! !
trap exit ERR               # ! ! ! TRAP ERR  ! ! !


perform_test(){
    local resultCall=$(...)

    if [[ -n ${resultCall} ]]; then
        return 0
    else
        return 1
    fi
}


##---------------- MAIN ----------------

perform_test
if [[ $? -eq 0 ]]; then
    #...
fi

#...

exit 0

更新:

根据@choroba的回答(使用if perform_test "sthg" ; then),返回 1没有像我预期的那样被陷阱捕获。

但不幸的是,这个解决方案对于我的用例来说是不完整的:如果函数perform_test产生错误(例如:找不到命令没有这样的文件......等),那么这个错误不再被陷阱和脚本捕获不会直接停...

那么,如何“捕获错误而不捕获return 1”?

这是一个说明它的工作示例:

#!/bin/bash

set -o pipefail  # trace ERR through pipes
set -o errtrace  # trace ERR through 'time command' and other functions
set -o nounset   ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit   ## set -e : exit the script if any statement returns a non-true return value

exit_handler (){
    error_code=$?
    if [[ ${error_code} -eq 0 ]]; then
        return; 
    fi

    echo "an error has occurred..."
    exit "${error_code}"
}

trap exit_handler EXIT      # ! ! ! TRAP EXIT ! ! !
trap exit ERR           # ! ! ! TRAP ERR  ! ! !


perform_test(){
    local resultCall=$1

    # file.txt doesn't exist
    cat file.txt

    if [[ -n ${resultCall} ]]; then
        echo ">> the variable is non empty"
        return 1
    else
        echo ">> the variable is empty"
        return 0
    fi
}


##---------------- MAIN ----------------

echo "first test"

if perform_test "sthg" ; then
    echo ">test1 has succeed"
else
    echo ">test1 has failed"
fi

echo "second test"

perform_test "sthg"
if [[ $? -eq 0 ]] ; then
    echo ">test2 has succeed"
else
    echo ">test2 has failed"
fi

echo "end"


trap - EXIT ERR

exit 0

产生以下输出:

first test
cat: file.txt: No such file or directory
>> the variable is non empty
>test1 has failed

second test
cat: file.txt: No such file or directory
an error has occurred...
4

2 回答 2

2

your_command args || {
    echo "Failed to xyz." >&2
    exit 1
}

或者

your_command args
if <test $?>; then
...
[elif ...
...
fi]

或者

your_command args
case "$?" in
...
esac

您还可以使用一个函数:

function error-exit {
    echo "$1" >&2
    exit 1
}
于 2014-06-25T13:30:05.457 回答
2

不要自己运行函数,直接在if条件下运行:

if perform_test ; then
    ...
fi

此外,在您最终退出之前,您应该清除陷阱。

trap '' EXIT
于 2014-06-25T13:14:19.197 回答