web-dev-qa-db-ja.com

bashで開始された実行可能ファイルの順序

Bashでtestコマンドを実行すると、-VARIABLE-(条件式を評価)組み込みユーティリティが起動します。

$ type test
test is a Shell builtin
$ type -a test
test is a Shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

ただし、上記のtype -a testの出力に示されているように、/ usr/local/binディレクトリには別のtestがあり、/ usr/binディレクトリには別のtestがあります。実行可能ファイルの順序はどのようになっていますか?つまり、組み込みコマンドは常に優先され、残りのコマンドは$ PATH変数のディレクトリ順序に依存していますか?さらに、開始された実行可能ファイルの順序を変更することは可能です。 testと入力すると、bash-builtin test?の代わりに/ usr/bin/testが開始されます。

14
Martin

最も優先順位が高いのはbashエイリアス、次に特別なビルトイン(POSIXモードのみ)、関数、ビルトイン、そして$PATHの検索です。

組み込みを実行するには、builtin testを使用します。
外部アプリケーションを実行するには、明示的なパス/bin/testを使用します。
関数とエイリアスを無視するには、command testを使用します。
エイリアスのみをバイパスするには、\testまたはその他の種類の展開を使用します。

enable testを使用して、組み込みを無効/有効にすることができます。

(以下のコメントに従って更新)
(bashにdisableが組み込まれているという誤った管理者編集を修正-実際にはenableしかない)

25
gena2x

組み込みコマンドは常に外部コマンドよりも優先されます。理論的根拠は、組み込みコマンドの方が速いということです(cdtest -o BASH_OPTIONなどのいくつかのケースでは、組み込みコマンドだけが目的の効果を持つことができます)。

場合によっては、外部コマンドにShellビルトインにはない機能があることがあります。その場合、明示的なパス(つまり、スラッシュを含む)を指定して外部コマンドを呼び出すことができます(これにより、$PATHの順序に関する懸念が回避されます)。外部パスをハードコーディングしたくないが、組み込みの使用を防ぎたい場合は、bashで"$(type -P test)"(大文字Pに注意)を使用できます"$(whence -p test)"、zshでは=test。外部コマンドの使用を強制するもう1つの方法は、commandビルトイン(command -p test …)を使用するか、envユーティリティ(env test …)を使用することです。

Zshでは、disable testを使用して組み込みを無効にできます。これは、組み込みがenable testで再度有効になるまで(現在のシェルまたはサブシェルに対して)永続的です。 bashでは、enable -n testを使用して無効にしたり、enable testを使用して再度有効にしたりすることもできます。

エイリアスまたは関数を使用して、alias test=/usr/bin/testtest () { /usr/bin/test "$@"; }などの別のコマンドを強制的に実行できます。そのようなエイリアスがある場合、その一部を引用することで、その使用を防ぐことができます。 \testは、通常の関数/ビルド/外部ルックアップを実行します。シェルとその設定によっては、関数のエイリアス定義が関数の読み取り時または実行時に展開される場合があることに注意してください。関数を定義している場合は、command testを使用して、関数のルックアップとエイリアスのルックアップを防ぐことができます(ここで、無効にしない限り、testビルトインが呼び出されます)。