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

☆樱花仙子☆ 提交于 2019-11-26 12:36:59

问题


I was using \"exit 1\" statement in my bash functions to terminate the whole script and it worked fine:

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....

But 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).


回答1:


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:

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




回答2:


You can use set -e which exits if a command exits with a non-zero status:

set -e 
func
set +e

Or grab the return value:

(func) || exit $?



回答3:


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 $?



回答4:


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"



回答5:


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

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


来源:https://stackoverflow.com/questions/9893667/is-there-a-way-to-write-a-bash-function-which-aborts-the-whole-execution-no-mat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!