私はスクリプトを書いていたときに、奇妙な問題に遭遇しました。文字列を出力して終了するエラー関数を呼び出す可能性のある一連の関数を含むスクリプトを入手した場合、シェルは終了します。なぜそれができるのか知っています。これは、関数呼び出しが呼び出し元と同じプロセス空間にあるためです(少なくともbashにあります)。関数内の出口は、提供された終了コードで現在のプロセスを終了します。例:
error()
{
echo $1
exit 1
}
fn()
{
if [ $# == 0 ]; then
error "Insufficient parameters."
fi
# do stuff
}
$ fn
Insufficient parameters.
[Shell terminates]
だから私の質問は、現在のシェルを終了せずに新しいサブシェルを生成せずに、関数スタックのすべての関数を終了できるでしょうか?
ありがとう
あなたはできる
exit() { return $1;}
その後
source ./your_script
懐疑論者への回答として、これは現在のシェルにのみ影響し、スポーンしたシェルには影響しません。
より有益なフォームは
exit() {
local ans
local line
read -p "You really want to exit this? " line
ans=$(echo $line)
case "$ans" in
Y);;
y);;
*)kill -INT $$;;
esac
unset -f exit
exit $1
}
関数のそれぞれにreturn
ステートメントを追加して、関数が呼び出す関数の戻り値を確認する必要があります。ファイルのソーシングは、$BASH_SOURCE
などの変数を除いて、現在のコンテキストにコードを切り取って貼り付けるようなものです。
または、fn
をシェルスクリプトとして定義して、exit
が必要なことを実行できるようにします(フォークが高すぎる場合を除く)。
return
ステートメントを使用しますが、呼び出しエラーの後にreturnを追加する必要があります
シェルには、一度に多くの関数呼び出しを巻き戻すための例外メカニズムはありません。戻り値を確認し、手動で最後まで返す必要があります。