95

Bash 関数で「exit 1」ステートメントを使用してスクリプト全体を終了していましたが、正常に機能しました。

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

しかし、次のように呼び出しても機能しないことに気付きました。

res=$(func)

サブシェルを作成し、「exit 1」がそのサブシェルを中止し、プライマリ シェルを中止しないことを理解しています....

しかし、どのように呼び出されても、実行全体を中止する関数を作成する方法はありますか? 実際の戻り値を取得する必要があるだけです (関数によってエコーされます)。

4

6 に答える 6

108

あなたができることは、シグナルが終了するようにトップレベルのシェルを登録してから、トップレベルのシェルTERMにを送信するTERMことです。

#!/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シグナルをトップレベルのシェルに送り返します。このシェルは、提供されたコマンド(この場合は)を使用してキャッチおよび処理され"exit 1"ます。

于 2012-03-27T16:54:55.317 に答える
46

set -eコマンドがゼロ以外の status で終了する場合は、 which exitを使用できます。

set -e 
func
set +e

または戻り値を取得します。

(func) || exit $?
于 2012-03-27T16:30:08.943 に答える
2

子プロセスは、親プロセスを暗黙的に強制的に閉じることはできません。ある種のシグナル伝達メカニズムを使用する必要があります。killオプションには、特別な戻り値が含まれる場合や、次のような信号を送信する場合があります。

function child() {
    local parent_pid="$1"
    local other="$2"
    ...
    if [[ $failed ]]; then
        kill -QUIT "$parent_pid"
    fi
}
于 2012-03-27T16:31:10.303 に答える
0

しかし、どのように呼び出されても、実行全体を中止する関数を作成する方法はありますか?

いいえ。

実際の戻り値を取得する必要があるだけです (関数によってエコーされます)。

あなたはできる

res=$(func)
echo $?
于 2012-03-27T16:34:45.707 に答える