How to abort only function on error, but do not the script?

vol*_*gas 6 linux error-handling bash

I have the following script:

#!/bin/bash

set -e

function do_it {
    rm this-file-does-not-exit
    echo "Continuing ..."
    echo "Done ..."
    return 0
}

if do_it ; then
    echo "Success"
else
    echo "Error"
fi
echo "End of script"
Run Code Online (Sandbox Code Playgroud)

Which produces:

rm: cannot remove 'this-file-does-not-exit': No such file or directory
Continuing ...
Done ...
Success
End of script
Run Code Online (Sandbox Code Playgroud)

The function is not aborted because running the function in the if statement disables set -e for the function (and can not be enabled). This is not what I want.

Running the function outside the if statement, and collecting the result, is not possible, because in this situation the complete script is aborted if the function fails:

#!/bin/bash

set -e

function do_it {
    rm this-file-does-not-exit
    echo "Continuing ..."
    echo "Done ..."
    return 0
}

do_it
if $? ; then
    echo "Success"
else
    echo "Error"
fi
echo "End of script"
Run Code Online (Sandbox Code Playgroud)

Produces:

rm: cannot remove 'this-file-does-not-exit': No such file or directory
Run Code Online (Sandbox Code Playgroud)

I would like the following:

  • the script aborts whenever a top-level command has a failure
  • functions are aborted whenever a command has a failure. The return code of the failing command is returned as function return code
  • failure in a function does not abort the script (only the function)

This can be implemented as follows:

#!/bin/bash

set -e

function do_it {
    rm this-file-does-not-exit || return $?
    echo "Continuing ..." || return $?
    echo "Done ..." || return $?
    return 0
}

if do_it ; then
    echo "Success"
else
    echo "Error"
fi
echo "End of script"
Run Code Online (Sandbox Code Playgroud)

Which produces what I want:

rm: cannot remove 'this-file-does-not-exit': No such file or directory
Error
End of script
Run Code Online (Sandbox Code Playgroud)

But this makes the implementation of the function completely unreadable: each line must be followed with a || return $?

Is there another way of aborting a function, and only the function, whenever an statement in the function fails?

Laj*_*pad 1

我不太擅长 bash 脚本编写,需要付出很多努力才能实现我的以下想法,但我认为这应该可行:

  • 实现一个功能
    • 它获取一个数组作为输入
    • 像您的示例一样,在失败时中断命令(作为字符串传递)
    • 返回一些内容,标识中断的位置以及原因(如果中断)
  • 当你想要你所描述的行为时
  • 构建您想要执行的命令的数组
  • 将此数组传递给函数
  • 处理响应