有没有办法编写一个bash函数来中止整个执行,无论它是如何被调用的?

Is there a way to write a bash function which aborts the whole execution, no matter how it is called?

我在bash函数中使用了"exit 1"语句来终止整个脚本,它工作得很好:

1
2
3
4
5
6
7
8
function func()
{
   echo"Goodbye"
   exit 1
}
echo"Function call will abort"
func
echo"This will never be printed"

但后来我意识到,当我这样叫它时,它并不能完成工作:

1
res=$(func)

我知道我创建了一个子shell,"出口1"中止了该子shell,而不是主shell……

但是,有没有一种方法可以写一个函数,不管它是如何调用的,它都会中止整个执行?我只需要得到实际的返回值(通过函数进行响应)。


您可以做的是注册顶级shell,让TERM信号退出,然后向顶级shell发送TERM信号:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
trap"exit 1" TERM
export TOP_PID=$$

function func()
{
   echo"Goodbye"
   kill -s TERM $TOP_PID
}

echo"Function call will abort"
echo $(func)
echo"This will never be printed"

因此,您的函数将一个TERM信号发送回顶层shell,该shell使用提供的命令捕获和处理,在本例中是"exit 1"


您可以使用set -e,当命令以非零状态退出时,该命令退出:

1
2
3
set -e
func
set +e

或者获取返回值:

1
(func) || exit $?


但是,有没有一种方法可以写一个函数,不管它是如何调用的,它都会中止整个执行?

不。

我只需要得到实际的返回值(通过函数进行响应)。

你可以

1
2
res=$(func)
echo $?

子进程无法强制父进程隐式关闭。你需要使用某种信号机制。选项可能包括一个特殊的返回值,或者用kill发送一些信号,比如

1
2
3
4
5
6
7
8
function child() {
    local parent_pid="$1"
    local other="$2"
    ...
    if [[ $failed ]]; then
        kill -QUIT"$parent_pid"
    fi
}