简体   繁体   English

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

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

I was using the "exit 1" statement in my Bash functions to terminate the whole script and it worked fine:我在我的 Bash 函数中使用“exit 1”语句来终止整个脚本,它运行良好:

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

But then I realized that it doesn't do the work when called like:但后来我意识到它在调用时不起作用:

res=$(func)

I understand that I created a subshell and "exit 1" aborts that subshell and not the primary one;我知道我创建了一个子shell,并且“退出 1”中止了该子shell,而不是主要的; is there a way to write a function which aborts the whole execution, no matter how it is called?有没有办法编写一个中止整个执行的函数,不管它是如何被调用的?

I just need to get the real return value (echoed by the function).我只需要获取真正的返回值(由函数回显)。

What you could do, is register the top level shell for the TERM signal to exit, and then send a TERM to the top level 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"

So, your function sends a TERM signal back to the top level shell, which is caught and handled using the provided command, in this case, "exit 1" .因此,您的函数将TERM信号发送回顶级 shell,使用提供的命令(在本例中为"exit 1" )捕获和处理该信号。

You can use set -e which exits if a command exits with a non-zero status :如果命令以非零状态退出,您可以使用set -e退出:

set -e 
func
set +e

Or grab the return value:或者获取返回值:

(func) || exit $?

I guess better is我想更好的是

#!/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"

A child process can't force the parent process to close implicitly.子进程不能强制父进程隐式关闭。 You need to use some kind of signaling mechanism.您需要使用某种信号机制。 Options might include a special return value, or perhaps sending some signal with kill , something like选项可能包括一个特殊的返回值,或者可能使用kill发送一些信号,例如

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

If you just need top be able to bomb out of your scripts from within a function, you can do:如果您只需要 top 能够从函数中轰炸您的脚本,您可以执行以下操作:

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

then elsewhere, within your functions, instead of using "exit", use "die".然后在其他地方,在你的函数中,而不是使用“exit”,使用“die”。

But is there a way to write a function which aborts the whole execution, no matter how it is called?但是有没有办法编写一个中止整个执行的函数,不管它是如何被调用的?

No.不。

I just need to get the real return value (echoed by the function).我只需要获取真正的返回值(由函数回显)。

You can你可以

res=$(func)
echo $?

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

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