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


14

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

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


コマンドを呼び出すときにフルパスを指定できます。例:/usr/bin/test -f "$file"...
jasonwryan

@jasonwryan私はこれを知っていますが、実行可能ファイルの開始順序を変更する方法があるかどうかだけ興味があります。
マーティン

回答:


25

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

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

で組み込みを無効/有効にすることが可能enable testです。

(以下のコメントによる更新)
(bashが持っていることを間違って管理編集を修正disable-実際には、唯一の存在である組み込みenable


1
@ 1_CR gena2xは正しいです。私の回答では、POSIXに準拠した関数よりも優先される特別な組み込み関数を省略しました(一部のシェルは非準拠ですが、bashはPOSIXモードでのみ準拠します)。
Gilles 'SO-邪悪なことをやめなさい'

1
推奨編集:コマンド(またはその一部)を引用するとき別名のように、無効化されている\testか、'test'またはtes't'
John Kugelman、2014年

2
それは全体像ではありません。あらゆる種類の展開(bashマニュアルでは、すべての置換、チルド展開などと呼ばれる展開)がエイリアスを無効にしているようです。私は試した。
gena2x

1
bashのmanページから引用:。。「各単純コマンドの最初の単語は、クォートされていない場合、それは別名であるかどうかをチェックし、その単語をエイリアスのテキストに置き換えられている場合、文字/$、バッククォート、および=上記のシェルメタ文字または引用文字は、エイリアス名に表示されない場合があります。」
John Kugelman、2014年

2
この情報のソースを見つけるのに役立つヒントの+1:これは、bashのマニュアルページの「コマンドの実行」セクションの2番目と3番目の段落にあります。
twan163 2016

6

組み込みコマンドは常に外部コマンドよりも優先されます。理論的根拠は、組み込みコマンドの方が高速であることです(cdまたは、やなど、組み込みコマンドのみが目的の効果を発揮できる場合もあります)。test -o BASH_OPTION

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

zshでは、で組み込みを無効にできますdisable test。組み込みコマンドがで再度有効になるまで、これは(現在のシェルまたはサブシェルに対して)永続的enable testです。bashでは、enable -n test無効化と再有効化についても同じことができenable testます。

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


wouldntはenvここにも適切では?
Steven Penny

それで、シェルがBusyBoxから実行される場合、他の、通常は同じBusyBoxからの外部コマンドは内部と見なされますか?例えば、私は完全な追加df、別名'DF'を取り出し、最初の位置にPATHにwhich df> busyboxの-実行DF / binに/ DFショーは/ opt / binに/ DF、しかし
papo

@papo which dfは、df実行内容を必ずしも表示するわけではありません。unix.stackexchange.com/questions/85249/...
ジル「SO-停止されて悪」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.