39

スクリプトを書いていたところ、奇妙な問題に遭遇しました。文字列を出力して終了するエラー関数を呼び出す可能性のある一連の関数を含むスクリプトをソースすると、シェルが終了します。私はそれがなぜそれをするのか知っています。これは、関数呼び出しが呼び出し元と同じプロセス空間にある (少なくとも bash にある) ためです。したがって、関数内の終了は、提供された終了コードで現在のプロセスを終了します。例:

error()
{
  echo $1
  exit 1
}

fn()
{
  if [ $# == 0 ]; then
    error "Insufficient parameters."
  fi
  # do stuff
}

$ fn
Insufficient parameters.
[shell terminates]

私の質問は、現在のシェルを終了したり、新しいサブシェルを生成したりせずに、関数スタック内のすべての関数を終了できますか?

ありがとう

4

5 に答える 5

37

シェルを終了せずに関数スタックを終了するには、次のコマンドを使用できます。

kill -INT $$

ピザが述べたように、これは Ctrl-C を押すようなもので、現在のスクリプトの実行を停止し、コマンド プロンプトにドロップダウンします。

 

 


注:ピザの回答を選択しなかった唯一の理由は、これが彼/彼女の回答に埋もれていて、直接回答されなかったためです.

于 2013-06-17T17:50:03.767 に答える
12

あなたはすることができます

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
}
于 2012-06-21T23:15:38.720 に答える
6

各関数にステートメントを追加returnして、関数が順番に呼び出す関数の戻り値を確認する必要があります。ファイルのソースは、コードを現在のコンテキストにカット アンド ペーストするようなものですが、$BASH_SOURCE.

fn別の方法として、シェル スクリプトとして定義することもできます。これにより、必要なことが実行されexitます (フォークが高すぎない限り)。

于 2012-06-21T15:30:59.110 に答える
2

usingreturnステートメントですが、エラーを呼び出した後に return を追加する必要があります

于 2012-06-21T15:21:08.347 に答える
2

シェルには、多くの関数呼び出しを一度に巻き戻すための例外メカニズムが実際にはありません。戻り値を確認し、手動で最後まで戻す必要があります。

于 2012-06-21T15:22:37.270 に答える