Yürütülebilir dosyaların sırası bash'ta başladı


14

testKomutu bash'de çalıştırırsam , test(koşullu ifadeyi değerlendirir) yerleşik yardımcı program başlatılır:

$ 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
$ 

Ancak, type -a testyukarıdaki çıktıda görüldüğü gibi, test/ usr / local / bin dizininde bir tane daha / / usr / bin dizininde bir tane daha vardır. Yürütülebilir dosyalar nasıl sıralanır, yani yerleşik komutlar her zaman tercih edilir ve sonra komutların geri kalanı $ PATH değişkenindeki dizin sırasına bağlıdır? Buna ek olarak, başlatılan yürütülebilir dosyaların sırasını değiştirmek mümkün müdür, örneğin yazdığımda testbash-builtin yerine / usr / bin / test başlatılır testmı?


Komutu çağırırken tam yolu belirtebilirsiniz, örn., /usr/bin/test -f "$file"...
jasonwryan

@jasonwryan Bunun farkındayım, ama sadece çalıştırılabilir dosyaların sırasını değiştirmenin bir yolu olup olmadığını merak ediyorum.
Martin

Yanıtlar:


25

En yüksek öncelik, bash takma adı, daha sonra özel yerleşikler (yalnızca POSIX modunda), daha sonra işlevler, ardından yerleşikler, ardından bir aramadır $PATH.

Bir yerleşkeyi yürütmek için tuşunu kullanın builtin test.
Harici bir uygulama çalıştırmak için, açık bir yolu kullanın: /bin/test.
İşlevleri ve takma adları yok saymak için kullanın command test.
Sadece takma adı atlamak, kullanmak \testveya başka herhangi bir genişletme yapmak.

Bir yerleşkeyi devre dışı bırakmak / etkinleştirmek mümkündür enable test.

(Aşağıdaki yorumlara göre güncellendi)
( disableBash'in yerleşik olduğu yanlış yönetici düzeltmesi düzeltildi - aslında sadece var enable)


1
@ 1_CR gena2x doğru. Cevabım POSIX'e göre işlevlerden öncelikli olan özel yerleşikleri atladı (bazı kabuklar uyumlu olmasa da bash yalnızca POSIX modunda uyuyor).
Gilles 'SO- kötü olmayı bırak'

1
Önerilen düzenleme: komutunu (veya onun herhangi bir bölümünü) alıntı yaparken adlar olduğu gibi devre dışıdır \testveya 'test'veya tes't'.
John Kugelman

2
Bu tam bir resim değil. Her türlü genişleme görünüyor (bash el kitabında, tüm ikame, tilde genişleme vb. Genişleme denir ) takma adları devre dışı bırakır. Denedim.
gena2x

1
Bash adam sayfasından alıntı:.. "Her basit komutun ilk sözcüğü, tırnak içine alınmamışsa, bir takma adı olup olmadığını görmek için kontrol edilir, bu sözcük takma adın yerine Eğer öyleyse karakterler /, $, backtick ve =ve yukarıda listelenen kabuk metakarakterlerinden veya alıntı karakterlerinden herhangi biri takma adda görünmeyebilir. "
John Kugelman

2
Bu bilginin kaynağını bulmama yardımcı olacak ipuçları için +1: bu bash man sayfasında, COMMAND EXECUTION, ikinci ve üçüncü paragraflar bölümünün altındadır.
twan163

6

Dahili komutlar her zaman harici komutlara tercih edilir. Bunun mantığı, yerleşik komutun daha hızlı olmasıdır (ve bazı durumlarda cdya da yalnızca yerleşik komut istenen etkiye sahip olabilir).test -o BASH_OPTION

Bazen harici komut, kabuk yerleşiminin sahip olmadığı yeteneklere sahip olabilir. Bu durumda, açık bir yol vererek (yani, eğik çizgi içeren) harici komutu çağırabilirsiniz (bu, siparişle ilgili endişeleri atlar $PATH). Eğer sabit koduna dış yolunu istemiyoruz ancak bunu yerleşiğine kullanılmasını önlemek istiyorsanız, kullanabileceğiniz "$(type -P test)"(not sermaye P, bash) "$(whence -p test)"ksh ve =testzsh içinde. Harici bir komutun kullanılmasını zorlamanın başka bir yolu da commandbuiltin ( command -p test …) yöntemini kullanmak veya envyardımcı programdan ( env test …) geçmektir .

Zsh'de bir yerleşkeyi ile devre dışı bırakabilirsiniz disable test. Bu, yerleşik yeniden etkinleştirilene kadar kalıcıdır (mevcut kabuk veya alt kabuk için) enable test. Bash'da, enable -n testdevre dışı bırakmak ve enable testyeniden etkinleştirmek için aynı işlemi yapabilirsiniz .

Örneğin, alias test=/usr/bin/testveya gibi farklı bir komutun yürütülmesini zorlamak için bir takma ad veya işlev kullanabilirsiniz test () { /usr/bin/test "$@"; }. Böyle bir takma adınız varsa, herhangi bir bölümünü alıntılayarak kullanımını engelleyebilirsiniz, örneğin \testnormal işlevi / yerleşik / harici aramayı gerçekleştirir. Kabuğa ve ayarlarına bağlı olarak, bir işlevdeki diğer ad tanımlarının bir işlev okunduğunda veya yürütüldüğünde genişletilebileceğini unutmayın. Bir işlev tanımladıysanız, command testişlev aramasının yanı sıra takma ad aramasını da önlemek için kullanabilirsiniz (bu nedenle burada testyerleşik devre dışı bırakılmadığı sürece çağrılacaktır).


envburada da uygun olmaz mıydı ?
Steven Penny

yani, kabuk BusyBox üzerinden çalışıyorsa, genellikle aynı BusyBox'ın harici komutları dahili olarak kabul edilir mi? Örneğin df, ilk konumda bir PATH'a tam ekledim , 'df' takma adını kaldırdım which df, / opt / bin /
df'yi

@papo which dfsize neyin dfçalıştığını göstermez . unix.stackexchange.com/questions/85249/…
Gilles 'SO- kötü olmayı bırak'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.