configure
によって生成された_config.status
_の次のコードスニペットを引用しました。
_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
のみを行う目的は何ですか?
_(exit 1);
_の実行は、ERR
トラップをトリガーする最も簡単な方法です。 _set -e
_が有効な場合は、即時終了もトリガーします。 (エラー条件をトリガーするには、コマンドが失敗する必要があります。サブシェルに失敗値を指定したexit
は、サブシェルが失敗する原因になります。)
_exit 1;
_は、これらのどちらも行いません。
そのため、{(exit 1); exit 1;}
を使用して、最初にERR
トラップを生成できます。これは、デバッグの目的で役立つ場合があります。その後、エラーを表示してスクリプトを終了します。
しかし、それはautoconf
ファイルで起こっていることではありません。 autoconf
スクリプトは、実行中に作成された一時ファイルをクリーンアップするためにEXIT
トラップに依存しています。 bash
を含むほとんどのシェルは、exit
トラップを呼び出す前に、EXIT
コマンドで提供された値からステータスを設定します。これにより、EXIT
トラップがエラーから呼び出されたか、正常終了から呼び出されたかを検出でき、トラップ操作の終了時に終了ステータスが正しく設定されていることを確認できます。
ただし、一部のシェルは連携しないようです。 autoconf
manual からの引用は次のとおりです。
autoconf
によって生成されるような一部のシェルスクリプトは、終了する前にトラップを使用してクリーンアップします。最後のシェルコマンドがゼロ以外のステータスで終了した場合、トラップもゼロ以外のステータスで終了するため、呼び出し元はエラーが発生したことを認識できます。残念ながら、Solaris _
/bin/sh
_などの一部のシェルでは、終了トラップが終了コマンドの引数を無視します。これらのシェルでは、トラップはそれが単純な出口によって呼び出されたか、出口1によって呼び出されたかを判別できません。出口を直接呼び出す代わりに、この問題の回避策がある_AC_MSG_ERROR
_マクロを使用します。
回避策は、_$?
_の終了ステータスbeforeがexit
コマンドの実行を確認することです。これにより、EXIT
トラップが実行されます。そして、確かに、その不思議なコードを挿入するのは_AC_MSG_ERROR
_マクロであり、余分な中括弧が付いています。
私が見る限り、これの目的はありません。サブシェルを開始してすぐに終了することで直接達成できることはありません。
このようなことは、コードを自動的に生成することの副作用である可能性が高いです。場合によっては、サブシェルでexit 1
を使用することが理にかなっている他のコマンドが実行されることがあります。最終的に、場合によっては機能を持たないステートメントを挿入できるようにすることで、生成コードが何らかの形で単純化され、毎回「クリーンなコード」を生成することがより複雑になる可能性が高くなります。それか、上記を生成したコードのどちらかが不十分に書かれているだけです:)
{...}
の寛大な使用はこれの別の例です。それらのほとんどは冗長ですが、すべての場合にそれらを挿入するコードを書く方が簡単です(おそらく、ブロックの出力/入力をリダイレクトしたい場合があります)。それらが必要とされていないものを区別し、それらを省略するのではなく。
(exit 1)
は、特定の終了コードを取得するためのおそらく最も単純な方法です(1の特殊なケースでは、もちろんもっと簡単な方法があります)。ただし、この場合は終了コードが検査されないため、これは理由ではありません。
exit
をサブシェルに配置する目的は、スクリプトを終了しないことです(ただし、特定の終了コードの生成にexitを使用します)。