İşte asla bilmek istemediğini düşündüğün tek şey:
özet
Bir Bourne benzeri kabuk betiğinde çalıştırılabilir bir dosyanın adını almak için (birkaç uyarı vardır; aşağıya bakınız):
ls=$(command -v ls)
Verilen bir komutun olup olmadığını anlamak için:
if command -v given-command > /dev/null 2>&1; then
echo given-command is available
else
echo given-command is not available
fi
Etkileşimli bir Bourne benzeri kabuğun isteminde:
type ls
which
Komut C-Shell'den kırık mirasıdır ve daha iyi Bourne benzeri kabuklar yalnız bırakılır.
Durumlarda kullanın
Bu bilgiyi bir betiğin parçası olarak veya kabuk isteminde etkileşimli olarak aramak arasında bir fark vardır.
Kabuk isteminde, tipik kullanım durumu şudur: bu komut garip davranır, ben doğru olanı mı kullanıyorum? Yazarken tam olarak ne oldu mycmd
? Ne olduğuna daha fazla bakabilir miyim?
Bu durumda, komutu gerçekten çağırmadan komutu çağırdığınızda kabuğunuzun ne yaptığını bilmek istersiniz.
Kabuk betiklerinde oldukça farklı olma eğilimindedir. Bir kabuk betiğinde, tek yapmak istediğin bir komutun nerede veya ne olduğunu bilmek istemenin bir nedeni yok. Genel olarak bilmek istediğiniz, yürütülebilir dosyanın yoludur, bu nedenle ondan daha fazla bilgi edinebilirsiniz (buna göre başka bir dosyaya giden yol gibi veya bu yoldaki yürütülebilir dosyanın içeriğinden bilgi okuyabilirsiniz).
Etkileşimli, hakkında bilmek isteyebilirsiniz tümmy-cmd
nadiren bu yüzden komut sistemi üzerinde kullanılabilir komutlar,.
Mevcut araçların çoğu (çoğu zaman olduğu gibi) etkileşimli olarak kullanılmak üzere tasarlanmıştır.
Tarih
İlk önce biraz tarih.
Erken Unix kabukları, 70'lerin sonlarına kadar hiçbir işlevi ya da takma adı bulunmayana kadar koyar. Sadece geleneksel çalışanlar aranıyor $PATH
. csh
1978 civarında tanıtılan diğer adları (gerçi csh
ilk edildi yayımlanan içinde 2BSD
ayrıca işlenmesini Mayıs 1979,) ve .cshrc
(gibi her kabuk kabuk özelleştirmek için kullanıcılar csh
okur .cshrc
bile değilken interaktif komut gibi).
Bourne kabuğu ilk kez 1979'da Unix V7'de piyasaya sürülürken, işlev desteği çok daha sonra eklendi (1984 SVR2'de), ve yine de hiçbir zaman bir rc
dosyaya sahip değildi ( .profile
ortamınızı yapılandırmak, kabuğunu değil ).
csh
Bourne kabuğundan çok daha popüler oldu (Bourne kabuğundan çok daha kötü bir sözdizimine sahip olsa da), etkileşimli kullanım için daha kullanışlı ve hoş özellikler ekliyordu.
In 3BSD
(1980), bir which
csh senaryo için eklenmiş csh
bir yürütülebilir belirlemenize yardımcı olmak için kullanıcılara ve siz bulabilirsiniz pek farklı bir senaryo which
(Solaris, HP / UX, AIX veya Tru64 gibi) günümüzde birçok ticari Unix'lerde.
Bu komut dosyası, kullanıcının okur ~/.cshrc
(tüm csh
komut dosyaları gibi çağrılmaz csh -f
) ve sağlanan komut adlarını takma adlar listesinde ve içinde $path
( csh
temeli koruyan dizi ) arar $PATH
.
İşte which
başlıyorsunuz, o zamanlar en popüler kabuk için ilk geldi (ve csh
90'lı yılların ortasına kadar hala popülerdi), bu kitaplarda belgelenmesinin ana nedenidir ve hala yaygın olarak kullanılmaktadır.
Bir csh
kullanıcı için bile , bu which
csh betiğinin size doğru bilgileri vermesi gerekmediğini unutmayın. Daha ~/.cshrc
sonra istemde tanımladığınızlardan değil, örneğin source
başka bir csh
dosyayı kullanarak tanımladığınız takma adları alır ve (bu iyi bir fikir olmasa da) PATH
yeniden tanımlanabilir ~/.cshrc
.
Bu which
komutu bir Bourne kabuğundan çalıştırmak, hala sizin için tanımlanmış takma adları arar ~/.cshrc
, ancak kullanmadığınız için bir tane yoksa csh
, muhtemelen size doğru cevabı verir.
Bourne kabuğuna, type
yerleşik komutla SVR2'de 1984'e kadar benzer bir işlevsellik eklenmedi . O (harici bir komut aksine) yerleşik olduğu gerçeği demektir olabilir o kabuğun iç yapıları erişimi nedeniyle size (bir dereceye kadar) doğru bilgiler vermek.
İlk type
komut, which
komut bulunmazsa , komut dosyasındaki bir başarısızlık çıkış durumu döndürmediği için benzer bir sorundan muzdaripti . Ayrıca, çalıştırılabilirler için, aksine which
, komut dosyalarında kullanımı daha az kolaylaştıran bir şey ls is /bin/ls
yerine çıktı /bin/ls
.
Unix Versiyon 8'in (vahşi doğada serbest bırakılmadığı) Bourne kabuğunun type
ismi değiştirildi whatis
. Ve plan9 (Unix kez arası olması halefi) kabuk rc
(ve bu gibi türevleri akanga
ve es
) sahip whatis
de.
80'lerin ortasında geliştirilen ancak 1988'den önce yaygın olarak bulunmayan Korn kabuğu (POSIX sh tanımının dayandığı bir alt küme), csh
Bourne kabuğunun üstüne birçok özellik (satır düzenleyici, takma ad ...) ekledi. . Birkaç seçenek ( kendi benzeri ayrıntılı çıktı sağlamak ve yalnızca çalıştırılabilir dosyaları aramak için (takma adlar / işlevler ...) değil ) alan kendi whence
yapısını (ek olarak type
) ekledi .-v
type
-p
AT&T ve Berkeley arasındaki telif hakkı sorunlarıyla ilgili kargaşaya tesadüf eseri, 90'ların başında 80'li yılların sonlarında birkaç ücretsiz yazılım kabuğu uygulaması ortaya çıktı. Almquist kabuğunun tamamı (BSD'lerdeki Bourne kabuğunun yerine konması gereken kül), ksh (pdksh) 'in bash
(FSF sponsorluğunda ) kamuya açık uygulaması zsh
1989 ve 1991 yılları arasında ortaya çıktı.
Ash, Bourne kabuğunun yerine geçmek anlamına gelse de, type
daha sonraya kadar (NetBSD 1.3 ve FreeBSD 2.3'te) bir yerleşime sahip değildi hash -v
. OSF / 1 ' /bin/sh
in type
her zaman 0' a OSF / 1 v3.x 'e geri dönen bir yapısı vardı. bash
bir yol eklemedi, whence
ancak yolu yazdırmak ( ister gibi ) ve eşleşen tüm komutları bildirmek için bir -p
seçenek ekledi . yapılan yerleşik ve katma gibi hareket komutu 's . hepsine sahip.type
type -p
whence -p
-a
tcsh
which
where
bash
type -a
zsh
fish
Kabuk (2005) bir sahip type
bir fonksiyonu olarak uygulanan komutu.
Bu which
arada csh betiği NetBSD'den (tcsh'de yerleşik olduğu ve diğer mermilerde pek kullanılmadığı) kaldırıldı ve (olarak whereis
çağrıldığında which
, yalnızca çalıştırılabilir dosyalara bakmadığı whereis
gibi davranır) eklenen işlevsellik çıkarıldı . OpenBSD’de ve FreeBSD’de, C’de yazılmış komutları yalnızca komutları arayanlar olarak değiştirdik .which
$PATH
which
$PATH
Uygulamalar
which
Farklı sözdizimi ve davranışı olan çeşitli Unices üzerinde bir komutun düzinelerce uygulaması vardır .
Linux'ta (içinde yerleşik olanlar yanında tcsh
ve zsh
) biz birkaç uygulamalarını bulabilirsiniz. Örneğin en son Debian sistemlerinde, komutları arayan basit bir POSIX kabuk betiğidir $PATH
.
busybox
ayrıca bir which
komut var.
Bir Orada GNU
which
muhtemelen en abartılı biri olan. which
Csh betiğinin diğer kabuklara ne yaptığını genişletmeye çalışır : takma adlarınızın ve işlevlerinizin ne olduğunu söyleyebilirsiniz, böylece size daha iyi bir cevap verebilir (ve bazı Linux dağıtımlarının bunun için bazı küresel takma adlar koyduğuna bash
inanıyorum) .
zsh
çalıştırılabilir yoluna genişletmek için birkaç operatöre sahiptir: =
dosya adı genişletme operatörü ve :c
geçmiş genişletme değiştiricisi (burada parametre genişletmeye uygulanır ):
$ print -r -- =ls
/bin/ls
$ cmd=ls; print -r -- $cmd:c
/bin/ls
zsh
, zsh/parameters
modülde ayrıca komut commands
dizisi ilişkisel dizi olarak tablo yapar :
$ print -r -- $commands[ls]
/bin/ls
Yardımcı whatis
program (Unix V8 Bourne kabuğundaki veya Plan 9 rc
/ ' es
dakiler hariç ) gerçekten sadece dokümantasyon için geçerli değildir (whatis veritabanını, man sayfası özeti olan whatis veritabanını tutar).
whereis
Ayrıca eklendi 3BSD
aynı zamanda which
o yazılmış olsa C
, değil csh
, aynı zamanda, içinde bulundukları ortama göre yürütülebilir, adam sayfası ve kaynak ama hiç de arama için kullanılır. Yani yine, bu farklı bir ihtiyaca cevap veriyor.
Şimdi, standart ön tarafta, POSIX command -v
ve -V
komutlarını belirtir (hangi POSIX.2008'e kadar isteğe bağlıydı). UNIX type
komutu belirtir (seçenek yok). Yani hepsi ( where
, which
, whence
herhangi bir standart belirtilmeyen)
Bazı sürümlere kadar type
ve command -v
örneğin bazılarının eski sürümlerinin posh
( pdksh
ikisine de sahip olmasına rağmen ) neden olmadığını açıklayan Linux Standard Base spesifikasyonunda isteğe bağlıydı . command -v
bazı Bourne kabuğu uygulamalarına (Solaris'teki gibi) de eklendi.
Bugünün Durumu
Bugünlerde durum şu type
ve command -v
tüm Bourne benzeri mermilerde her yerde bulunmakta (her ne kadar @jarno tarafından belirtildiği gibi bash
, POSIX modunda değilken veya yorumlarda aşağıdaki Almquist kabuğunun bazı torunları). tcsh
kullanmak isteyeceğiniz tek kabuktur which
(çünkü orada yoktur type
ve which
yerleşiktir).
Dışındaki kabukları içinde tcsh
ve zsh
, which
sürece hiçbir ad veya işlev aynı isimle kızımız hiçbirinde olduğu gibi size verilen yürütülebilir yolunu söyleyebilir ~/.cshrc
, ~/.bashrc
ya da herhangi bir kabuk başlatma dosyası ve tanımlamaz $PATH
Gözlerinde farklı ~/.cshrc
. Tanımlanmış bir takma adınız veya işleviniz varsa, bu konuda size söyleyebilecek ya da söylemeyebilir veya yanlış bir şey söyleyebilirsiniz.
Tüm komutları belirli bir adla bilmek istiyorsanız, taşınabilir bir şey yok. Sen kullanmayı tercih where
bölgesi tcsh
veya zsh
, type -a
içinde bash
ya zsh
, whence -a
ksh93 ve diğer kabuklarda kullanabileceğiniz type
birlikte which -a
hangi çalışabilir.
öneriler
Yol adını çalıştırılabilir dosyaya alma
Şimdi, bir betiğin çalıştırılabilir kodunun adını almak için birkaç uyarı var:
ls=$(command -v ls)
Bunu yapmanın standart yolu olurdu.
Ancak birkaç sorun var:
- Çalıştırılabilir dosya yolunu, çalıştırmadan bilmek mümkün değildir. Tüm
type
, which
, command -v
... tüm kullanım sezgiselleri yolunu bulmak için. Onlar aracılığıyla döngü $PATH
bileşenleri ve yürütme iznine sahip olan ilk dizin olmayan dosyasını bulun. Bununla birlikte, kabuğa bağlı olarak, komut çalıştırıldığında, birçoğu (Bourne, AT&T ksh, zsh, ash ...) sistem çağrısı bir hata ile dönmeyene $PATH
kadar onları sadece yürütecektir. execve
. Örneğin, $PATH
içeriyorsa /foo:/bar
ve yürütmek istiyorsanız ls
, önce yürütmeye çalışacaklar /foo/ls
veya başarısız olursa /bar/ls
. Şimdi yürütme/foo/ls
Yürütme izniniz olmadığından ancak geçerli bir çalıştırılabilir olmadığından başka nedenlerden dolayı başarısız olabilir. için yürütme izniniz varsa command -v ls
rapor /foo/ls
eder /foo/ls
, ancak geçerli bir ls
çalıştırılabilir /bar/ls
değilse /foo/ls
, çalıştırma işlemi gerçekten çalışabilir .
- Eğer
foo
bir yerleşik ya da fonksiyon ya da diğer adı olan, command -v foo
döner foo
. Boş dizgiyi içeriyorsa ve geçerli dizinde çalıştırılabilir bir dosya varsa ash
, pdksh
veya gibi bazı kabuklarda zsh
da döndürülebilir . Bunu dikkate almanız gerekebilecek bazı durumlar vardır. Örneğin, yerleşiklerin listesinin kabuk uygulamasına bağlı olduğunu unutmayın (örneğin, bazen meşgul kutusu için yerleşiktir ) ve örneğin ortamdan işlevler alabilir.foo
$PATH
foo
mount
sh
bash
- Eğer
$PATH
(tipik olarak göreceli yol bileşenleri içeren .
ya da her ikisi geçerli dizine bakınız başka bir şey olabilir boş dize), kabuk bağlı command -v cmd
olabilir çıkış mutlak bir yolu. Bu nedenle koşarken elde ettiğiniz yol, başka bir yerden command -v
sonra geçerli cd
olmayacaktır.
- Anekdot: eğer ksh93 kabuk ile,
/opt/ast/bin
(yani tam yol inanıyorum farklı sistemlerde farklı olabilir gerçi) senin içinde $PATH
, ksh93 mevcut birkaç ekstra yerleşiklerinden (yapacaktır chmod
, cmp
, cat
...), ama command -v chmod
dönecektir /opt/ast/bin/chmod
o yolun kokan bile t var.
Bir komutun olup olmadığını belirleme
Belirli bir komutun standart olarak olup olmadığını öğrenmek için şunları yapabilirsiniz:
if command -v given-command > /dev/null 2>&1; then
echo given-command is available
else
echo given-command is not available
fi
Nerede kullanmak istersin? which
(t)csh
İçinde csh
ve tcsh
fazla seçeneğiniz yok. İçinde tcsh
olduğu gibi iyidir which
. Bu csh
, which
birkaç durumda istediğiniz şeyi yapamayabileceğiniz sistem komutu olacaktır .
komutları sadece bazı mermilerde bul
Kullanmanın mantıklı olabileceği bir durum which
, bir komutun yolunu bilmek, potansiyel kabuk yapılarını veya işlevlerini bash
, csh
(değil tcsh
) dash
ya da Bourne
kabuk komut dosyalarında yok sayarak whence -p
(gibi ksh
ya da zsh
) kabuk komut dosyalarını görmezden gelmek isteyip istemediğinizdir. , command -ev
(like yash
), whatis -p
( rc
, akanga
) veya mevcut olan ve script olmayan sistemlerdeki bir yerleşik which
(like tcsh
veya zsh
) .which
csh
Bu koşullar yerine getirilirse, o zaman:
echo=$(which echo)
Size ilk yolunu verecekti echo
içinde $PATH
(köşe durumlar haricinde) ne olursa olsun, olsun echo
da bir kabuk yerleşik / takma / fonksiyon ya da olmamak olur.
Diğer kabuklarda, tercih edersiniz:
- zsh :
echo==echo
veya echo=$commands[echo]
veyaecho=${${:-echo}:c}
- ksh , zsh :
echo=$(whence -p echo)
- yaş :
echo=$(command -ev echo)
- rc , akanga :
echo=`whatis -p echo`
(boşluklu yollara dikkat et)
- balık :
set echo (type -fp echo)
Yapmanız gereken tek şey bu komutu çalıştırmak ise echo
, onun yolunu almak zorunda değilsiniz, sadece şunu yapabilirsiniz:
env echo this is not echoed by the builtin echo
Örneğin tcsh
, yerleşimin which
kullanılmasını önlemek için :
set Echo = "`env which echo`"
harici bir komuta ihtiyaç duyduğunuzda
Kullanmak isteyebileceğiniz başka bir durum which
, aslında harici bir komuta ihtiyaç duyduğunuzda olabilir . POSIX, tüm kabuk yerleşiklerinin (gibi command
) harici komutlar olarak da kullanılabilmesini gerektirir , ancak ne yazık ki command
pek çok sistem için geçerli değildir . Örneğin command
, Linux tabanlı işletim sistemlerinde bir komut bulmak nadirdir which
( birçoğunda bir komut olsa da (farklı seçenekler ve davranışlar içeren farklı olsalar)).
Harici bir komut isteyebileceğiniz durumlar, bir POSIX kabuğunu çağırmadan bir komutu yerine getireceğiniz her yerde olur.
system("some command line")
, popen()
... C veya çeşitli dillerde yerine getirdiği işlevleri komut satırı ayrıştırmak için bir kabuk çağırmak, böylece do system("command -v my-cmd")
onları çalışma yapmak. Bunun bir istisnası, perl
herhangi bir özel kabuk karakteri (boşluk dışında) görmezse, kabuğu en iyi duruma getirmesi olabilir . Bu aynı zamanda backtick operatörü için de geçerlidir:
$ perl -le 'print system "command -v emacs"'
-1
$ perl -le 'print system ":;command -v emacs"'
/usr/bin/emacs
0
$ perl -e 'print `command -v emacs`'
$ perl -e 'print `:;command -v emacs`'
/usr/bin/emacs
Yukarıdakilerin eklenmesi, orada bir kabuk çağırmaya :;
zorlar perl
. Kullanarak which
, bu numarayı kullanmak zorunda kalmazsınız.
which
etkileşimli bir kabuk bağlamı varsayıyor. Bu soru etiketlendi / taşınabilirlik. Bu yüzden, soruyu bu bağlamda "which
verilen adın ilk çalıştırılabilirini bulmak yerine ne kullanmalıyım" olarak yorumluyorum$PATH
. Çoğuwhich
gerçek dünyada taşınabilir kabuk komut dosyalarında sadece akademik ilgi alanı bulunan takma adlar, yerleşikler ve işlevlerle başa çıkmanın en çok yanıtı ve nedeni . Yerel olarak tanımlanmış diğer adlar, bir kabuk betiği çalıştırılırken miras alınmaz (kaynak göstermediğiniz sürece.
).