私は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」がそのサブシェルをアボートし、プライマリサブシェルはアボートしないことを理解しています。
しかしどのように呼び出されても実行全体を中止する関数を書く方法はありますか?本当の戻り値を取得する必要があります(関数によってエコーされます)。
couldを実行すると、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"
。
しかし、どのように呼び出されても、実行全体を中止する関数を記述する方法はありますか?
いいえ
実際の戻り値を取得する必要があります(関数によってエコーされます)。
できます
res=$(func)
echo $?
子プロセスは、親プロセスを暗黙的に閉じることはできません。何らかの種類の信号メカニズムを使用する必要があります。オプションには特別な戻り値が含まれるか、kill
を使用して何らかの信号を送信する場合があります。
function child() {
local parent_pid="$1"
local other="$2"
...
if [[ $failed ]]; then
kill -QUIT "$parent_pid"
fi
}
私はより良いと思います
#!/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"