如何捕获函数的返回值

时间:2014-06-25 13:10:22

标签: bash function return bash-trap

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

例如,如果perform_test 返回1 ,则脚本结束,因为非零返回值被捕获并通过调用{来处理{1}}功能。

如何避免此行为?

由于

这里是剧本:

exit_handler

更新

根据 @choroba 的答案(使用#!/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 ),返回1 并未被陷阱捕获为我期待。

但不幸的是,这个解决方案对我的用例来说是不完整的:如果函数if perform_test "sthg" ; then产生错误(例如:命令未找到没有这样的文件...... 等等,然后这个错误不再被陷阱捕获了。脚本不会直接停止......

那么,如果没有捕获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

2 个答案:

答案 0 :(得分:2)

不要自行运行该功能,直接在if条件下运行:

if perform_test ; then
    ...
fi

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

trap '' EXIT

答案 1 :(得分:1)

待办事项

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
}