繁体   English   中英

如何有效地从函数中止执行 Bash 脚本

[英]How to effectively abort the execution of a Bash script from a function

我在我的 Bash 函数中使用“exit 1”语句来终止整个脚本,它运行良好:

function func()
{
   echo "Goodbye"
   exit 1
}
echo "Function call will abort"
func
echo "This will never be printed"

但后来我意识到它在调用时不起作用:

res=$(func)

我知道我创建了一个子shell,并且“退出 1”中止了该子shell,而不是主要的; 有没有办法编写一个中止整个执行的函数,不管它是如何被调用的?

我只需要获取真正的返回值(由函数回显)。

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

#!/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,使用提供的命令(在本例中为"exit 1" )捕获和处理该信号。

如果命令以非零状态退出,您可以使用set -e退出:

set -e 
func
set +e

或者获取返回值:

(func) || exit $?

我想更好的是

#!/bin/bash
set -e
trap "exit 1" ERR

myfunc() {
     set -x # OPTIONAL TO SHOW ERROR
     echo "Exit with failure"
     set +x # OPTIONAL
     exit 1
}
echo "BEFORE..."
myvar="$(myfunc)"
echo "AFTER..But not shown"

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

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

如果您只需要 top 能够从函数中轰炸您的脚本,您可以执行以下操作:

function die () {
    set -e
    /bin/false
}

然后在其他地方,在你的函数中,而不是使用“exit”,使用“die”。

但是有没有办法编写一个中止整个执行的函数,不管它是如何被调用的?

不。

我只需要获取真正的返回值(由函数回显)。

你可以

res=$(func)
echo $?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM