`{{(exit 1); 出口1; }; } `意味?


28

config.statusによって生成されconfigureたからの次のコードスニペットを引用しました。

if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi

コードスニペットでは、何をし{ (exit 1); exit 1; };ますか?exitサブシェルでのみ行う目的は何ですか?

回答:


33

実行(exit 1);は、ERRトラップをトリガーする最も簡単な方法です。set -e有効になっている場合は、即時終了もトリガーします。(エラー状態をトリガーするには、コマンドが失敗する必要があります。exitサブシェルに失敗値があると、サブシェルが失敗します。)

exit 1; それらのいずれも行いません。

したがって{(exit 1); exit 1;}、最初にERRトラップを生成するために使用できます。トラップはデバッグの目的で役立つことがあり、それからスクリプトをエラー表示で終了します。

しかし、それはautoconfファイルで起こっていることではありません。autoconfスクリプトEXITは、実行中に作成された一時ファイルをクリーンアップするためにトラップに依存します。を含むほとんどのシェルは、トラップを呼び出す前bashexitコマンドで指定された値からステータスを設定しますEXIT。これにより、EXITトラップがエラーから呼び出されたか正常終了から呼び出されたかを検出でき、トラップ操作の終了時に終了ステータスが正しく設定されていることを確認できます。

ただし、明らかに一部のシェルは連携しません。autoconfマニュアルからの引用です:

によって生成されるようないくつかのシェルスクリプト autoconf、トラップを使用して終了前にクリーンアップします。最後のシェルコマンドがゼロ以外のステータスで終了した場合、トラップはゼロ以外のステータスで終了するため、呼び出し側はエラーが発生したことを知ることができます。

残念ながら、Solarisなどの一部のシェルで/bin/shは、終了トラップはexitコマンドの引数を無視します。これらのシェルでは、トラップは、単純な出口で呼び出されたか、出口1で呼び出されたかを判別できません。出口を直接呼び出す代わりにAC_MSG_ERROR、この問題の回避策があるマクロを使用してください。

回避策は、コマンドが実行される前に$?終了ステータスを確認し、トラップが実行されたときに確実にその値になるようにすることです。そして、確かに、それはその好奇心code盛なコードを挿入するマクロです。exitEXITAC_MSG_ERROR


なぜfalse代わりに単に実行しないの(exit 1)ですか?
ルスラン14年

3
@Ruslan:2つの問題。(1)最も重要:falseステータスコードを設定させず、ゼロ以外のステータスが返されるという保証はありません。(2)false通常は組み込みではないため、子プロセスが必要です。対照的に、ほとんどのシェルは、子を処理するために生成することを回避でき(exit 1)ます。
リチ14年

8

私が見る限り、この目的はありません。サブシェルを起動してすぐに終了することで直接達成できるものはありません。

このようなことは、おそらくコードを自動生成する副作用です-場合によっては、サブシェルで実行される他のコマンドがある可能性があります exit 1が意味なす。最終的には、場合によっては機能を持たないステートメントを挿入し、「クリーンなコード」を毎回生成することがより複雑になるため、生成コードが何らかの形で単純化される可能性が高くなります。それまたは上記を生成したコードのどちらかが不完全に書かれているだけです:)

の寛大な使用は{...}これの別の例であり、それらのほとんどは冗長ですが、すべてのケースでそれらを挿入するコードを書く方が簡単です(ブロックの出力/入力をリダイレクトしたい場合があります)必要のないものは省略します。


それには目的があります。@riciの回答を参照してください。
古いプロ14年

1

(exit 1)は、特定の終了コードを取得するための、おそらく最も簡単な方法です(1の特別な場合には、もちろん簡単な方法があります)。ただし、この場合、終了コードは検査されないため、これは理由ではありません。

exitサブシェルを配置する目的は、スクリプトを終了しないことかもしれません(ただし、特定の終了コードの生成にexitを使用します)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.