簡體   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