“/ Bin / [” tam olarak nasıl çalışır?


50

Klasörde /binbir [program olduğuna her zaman şaşırdım .

Buna benzer bir şey yaptığımızda buna denir if [ something ]mi?

[Programı açıkça bir kabuk içinde çağırarak karşılık gelmesini ister ]ve kapatma braketini sağladığımda, braketler arasına ne taktığım farketmez.

Söylemeye gerek yok, yani ne, çalışmayan bir program hakkında yardım alma konusunda olağan yolu man [ne de [ --helpişler.


11
@IporSircer komuta [atıfta bulunur , öyle testolmasın expr, öyle olmalıman test
Sergiy Kolodyazhnyy

8
man '['benim için iyi çalışıyor - ya alıntı yapmayı unuttun [ya da "eserler" in farklı bir tanımına sahipsin.
Toby Speight

3
Birkaç uyarı: [argümanlarını değerlendirir, bu yüzden aralarında boşluk olması gerekir. [ a=b ]Bir karşılaştırma değil: her zaman doğru olacaktır (tek bir dizedir: "a = b", her zaman doğru olarak değerlendirilir ) Ve argüman sayısını 4 olarak sınırlamanız gerekir (en son uygulamalar daha fazla izin verecek olsa da .. 4 ile sınırlandırılması onu daha taşınabilir kılar.Örneğin: [ "a" = "b" ]zaten 4 argüman var: "a" "=" "b" ve gerekli olmayan test argümanı: "]". Daha fazlasına ihtiyacınız varsa: örneğin zincir testleri:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
Olivier Dulac

1
@OlivierDulac a !kendi kendine ( kaçışmamış ve işaretsiz ) değiştirilmeyecek ve daha da iyi olacaktır if ! [ .... Kullanılan bash genişlemelerinin tümü, !en azından diğer karakterleri içerir
muru

3
Ayrıca içinde bir [-builtin bulunduğunu bash(ve muhtemelen diğer kabukları da) ve bunun yerine kullanılabileceğini not etmelisiniz /bin/[. Ayrıca test, birçok sistemde sembolik bir bağlantı olan /bin/[(ya da tam tersi) olan -komut vardır - ama diğerleri için ayrı bir komuttur.
Baard Kopperud

Yanıtlar:


63

[Komutası işi testi ifadeleri değerlendirmektir. İfade doğru olduğunda başka bir şeyle ( yanlış anlamına gelir ) çözüldüğünde 0 çıkış durumuyla (bu, doğru anlamına gelir ) döndürür.

Hiçbir şey yapmaması değil, sadece sonucunun çıkış durumunda bulunmasıdır. Bir kabukta, $?Bourne benzeri kabukları için ya da $statusdiğer çoğu kabuğunda son komutun çıkış durumunu öğrenebilirsiniz (balık / rc / es / csh / tcsh ...).

$ [ a = a ]
$ echo "$?"
0
$ [ a = b ]
$ echo "$?"
1

Gibi diğer dillerde perl, örneğin şu değerlerin döndürdüğü gibi çıkış durumu döndürülür system():

$ perl -le 'print system("[", "a", "=", "a", "]")'
0

Tüm Bourne benzeri mermilerin (ve fish) yerleşik bir [komutu olduğunu unutmayın. Bir /binbaşka kabuk kullandığınızda genellikle yalnızca idam edileceğini veya aşağıdakilere benzer işlemler sırasında env [ foo = bar ]veya find . -exec [ -f {} ] \; -printya o perlyukarıdaki komutla ...

[Komut ayrıca bilinir testisim. Çağrıldığında testkapanış ]argümanı gerektirmez .

Sisteminizde bir adam sayfası olmasa da [, muhtemelen bir tane var test. Fakat yine de, uygulamanın /bin/[veya /bin/testuygulamanın belgeleneceğini unutmayın . [Kabuğunuzdaki yerleşikler hakkında bilgi edinmek için, kabuğunuzun belgelerini okumalısınız.

Bu yardımcı programın geçmişi ve [[...]]ksh test ifadesiyle olan fark hakkında daha fazla bilgi için , buradaki diğer soru ve cevaplara bir göz atmak isteyebilirsiniz .


Her zamanki gibi iyi. @Bregalad sorusunun altına eklediğim yorumları eklemek isteyebilirsiniz? ya da belki bazı ekstralar? Bu şekilde cevap, “tam olarak nasıl çalıştığı” konusunda daha da eksiksiz olacaktır (“]” hakkında benden daha doğru bir bilgi verdiğinizi unutmayın. ^^.)
Olivier Dulac

“Tüm Bourne benzeri mermiler (ve balıklar) yerleşik bir [komuta” sahipler. Bu, 21. yüzyılda pratikte doğru, ama kesinlikle bir kabuk kullanmadan kullandığımdan eminim [. Bourne varyantı mı yoksa antika bir kül versiyonu mu olduğunu hatırlamıyorum.
Gilles 'SO- kötülük olmayı bırak'

Bourne kabuğu iki uygulanmaktadır @Gilles [ve testUNIX sistem III builtins olarak. Ondan önce, hiçbir şey yoktu [ve testsadece harici bir ikili komut vardı.
jlliagre

@Gilles, orijinal külün test yapılı olmasına rağmen (expr ile birleştirilmiştir), fakat isteğe bağlı olarak . İn.ulm.de/~mascheck/various/ash’a göre, BSD’ler 2000’ye kadar test yaptırmadılar. “Modern” ekledim.
Stéphane Chazelas,

Neden dünyada yapmak istersin find . -exec [ f {} ] \; -print? Komuta find . -type f -printaynı şeyi çok daha verimli bir şekilde yapardı ...
Bu benim gerçek adım değil

41

Klasörde /binbir [program olduğuna her zaman şaşırdım .

Şaşırmakta haklısın. Bu, nadir bulunan POSIX komutlarından biridir, null yardımcı programına ( :) sahip, komut dosyalarına izin verilen karakter kurallarına uymaz (taşınabilir dosya adı karakter kümesi).

: Biz böyle bir şey yaptığını zaman ne denir edilir mi if [ something ]?

Tam olarak ama o olmadan da kullanılabilir if.

[Programı açıkça bir kabuk içinde çağırarak karşılık gelmesini ister ]ve kapatma braketini sağladığımda, braketler arasına ne taktığım farketmez.

Görünür bir şey yapmaz, ancak gerçekte kullanıldığı zamankiyle aynı şeyi yapar if, yani parantez içine ne koyduğunuza bağlı olarak çıkış durumunu 0 (doğru) veya başka bir şey (yanlış) olarak ayarlar. Bu (bir sebepten dolayı) testkomutla aynı davranıştır ; tek fark, sonu bulmasıdır ]. Detaylar man testiçin bakınız.

Söylemeye gerek yok, yani ne, çalışmayan bir program hakkında yardım alma konusunda olağan yolu man [ne de [ --helpişler.

Bu, İşletim Sisteminize bağlıdır. man [kesinlikle benim için birkaç ana Gnu / Linux dağıtımında çalışıyor, ancak Solaris'te yok.

[ --helpYine de sözdizimi kırdığı için uygulamaya bağlı olarak çalışmayabilir veya çalışmayabilir, sona erebilir ]. Üstelik için POSIX standardı test/ [komutu açıkça dahil tüm seçenekleri, dışladı --böylece hem seçenek fesih [ --help ]ve test --helpdönmek gerekiyor trueve tasarımı ile sessiz ol. Parantezlerin içine veya sonrasına ne koyduğunuzu [ve seçeneklere (örneğin -f file, -n stringbeğeniler gibi) benzeyenlerin seçenek değil, işlenen olduğunu unutmayın .

Tüm modern Bourne tarzı kabuk tercümanlar (gibi bash, ksh, dashve zshbirkaç isim) uygulamak test/ [bunları kullandığınızda bir yerleşik böylece sağ el ile sayfa kabuğunun kimse, olabilir başvurmak üzere dahili yarar testbir.

Unix System III'ten (1981) önce, Bourne kabuğu testyardımcı programı bir yerleşik olarak uygulamadı, bu nedenle sadece harici ikili komut uygulaması mümkün oldu. [Unix Sistem III'e kadar bir komut (iç ya da yerleşik) yoktu, bu nedenle örneğin Unix Sürüm 7 altında şunu yazmanız gerekiyordu:

if test something ; then

onun yerine:

if [ something ] ; then

"dostum [kesinlikle benim için Gnu / Linux dağıtımlarında kesinlikle işe yarıyor" Hmm .. Centos (kuşkusuz 6,8) açıkça yeterince ana değil :) man testçalışıyor ama man [ öte yandan cygwin ortamım hakkında bir şey bilmiyor man [!
Adam

1
@Adam Evet, haklısın, tüm ana Linux dağıtımlarını yazmamama rağmen , sadece benim için çalıştığını düşündüğümden daha yeni (yani test ettiğim testlerde). OL 7.2 (RHEL 7.2) klonu ve Nane 17.1 (Ubuntu 14.04).
jlliagre

man [Manjaro (Arch Linux tabanlı) üzerinde çalışıyor gibi görünmüyor. İçin manuel testlistelerinin [ --helpyardım gösterebilir ancak ilginçtir, öyle değil ve bunun yerine bir eksik hakkında şikayet gerektiğini geçerli çağırma olarak ]ile aynıdır, --version. ]Bunu eklemek hiçbir şey yapmaz, bu yüzden dışında yardım almak imkansız görünüyor man test.
Darkhogg

@Darkhogg /usr/bin/[ --helpveya deneyebilirsiniz /bin/[ --help.
jlliagre

1
@jlliagre Tamamen haklısın, ben yerleşikleri kullanıyordum. env [ --helphem de /usr/bin/[ --helptamamen iyi iş (her ne kadar alıntı /usr/bin/[ya da zsh şikayet gerek) rağmen .
Darkhogg

10

[aslında daha yaygın olarak testkomut olarak bilinir . Bu komutun tipik kullanımı, basitçe ifadeleri değerlendirmek ve durumlarını döndürmektir - doğru veya yanlış. Genellikle if-then-else-fiifadelerde kullanılır , ancak ifadelerin dışında ifdiğer komutları shell &&veya ||operatörler aracılığıyla koşullu olarak çalıştırmak için de kullanılabilir .

$ [ -e /etc/passwd  ] && echo "File exists"
File exists

$ test -e /etc/passwd && echo "File exists"
File exists

Daha spesifik olarak, değerlendirme çıkış durumu aracılığıyla diğer komutlara iletilir. Bazı programlar, farklı olay türlerini belirtmek için çıkış durumunu çıkarmayı seçebilir - program başarıyla tamamlandı, yürütme sırasında gerçekleşen belirli bir tür hata veya sözdizimi hataları. testKomut durumunda, 0doğru ve 1yanlış olanı belirtir. Stephan'ın da belirttiği gibi, sözdizimi hataları çıkış durumunu üretir 2.

Konumu sisteminize bağlıdır ve ayrıca yaptığınız zaman neden man sayfasını görmediğinizi de açıklar man [. Örneğin, FreeBSD'de altında /bin. Linux'ta (veya benim özel durumumda, Ubuntu 16.04) /usr/bin/. Bunu yaparsanız man [veya man testbir Linux sisteminde yaparsanız, aynı belgelerin açık olduğunu göreceksiniz. Ayrıca, kabuğunuzun kendi uygulamasına sahip olabileceğini not etmek de önemlidir test.

Bu komutun, Korn kabuğunun uygulanmasının (genellikle "koşullu ifade" olarak adlandırılan , çift köşeli parantezle referans olarak bilinir ) çözmeyi istediği meselelere sahip olduğu da belirtilmelidir . Bu özellik ayrıca ve gibi diğer mermiler tarafından da kullanılır .[[ "$USER" = "root" ]]bashzsh


/usr/bin/Amazon Linux için de.
franklinsijo

@ StéphaneChazelas Teşekkürler. Buna göre düzenlenmiş cevap
Sergiy Kolodyazhnyy

3

Ne işe yarar man [ne de[ --help

Bazı dağıtımlarda (örneğin Ubuntu), man [bir bağlantı izler test(1). Diğerlerinde (örneğin, Kemer), durum böyle değil. (Ancak testman sayfası [aynı zamanda doküman kullanımını da yapar )


type -a [ hem bir kabuk yerleşik hem de çalıştırılabilir olduğunu gösterir.

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

bash builtin [ --helpsadece bir hata mesajı yazdırır. (Ancak bir yerleşik olduğundan, help [bash man sayfasına / belgelerine bakabilir veya bakabilirsiniz).

/usr/bin/[ --help şunlarla başlayan tam yardım çıktısını (GNU Coreutils sürümü için) yazdırır:

$ /usr/bin/[ --help
Usage: test EXPRESSION
  or:  test
  or:  [ EXPRESSION ]
  or:  [ ]
  or:  [ OPTION
Exit with the status determined by EXPRESSION.

      --help     display this help and exit
      --version  output version information and exit

ve sonra, EXPRESSION için izin verilen sözdizimini açıklar.

Bu, bunu öğrenmiş olmanızın başka bir yoludur [ve testeşdeğerdir.


BTW, bash için programlama yapıyorsanız (veya tek gömlekleri etkileşimli olarak yazıyorsanız), [[yerine öneririm [. Birkaç yönden daha iyi, Serg'in cevabındaki bağlantıları gör.


2

[argümanlarında yer alan ifade, doğru olarak kabul edilirse, komut argümanlarında yer alan ifade yanlış olarak kabul edilirse, sıfır olmayan çıkış durumu olarak döndürülür. Ayrıca son argümanı değilse hata mesajı ile başarısız olur ](bu sadece estetik nedenlerle yapılır).

Örneğin:

[ hello ]
echo "Exit-status of [ hello ] is:" $?
[ abc = abc ]
echo "Exit-status of [ abc = abc ] is:" $?
[ ]
echo "Exit-status of [ ] is:" $?
[ abc = def ]
echo "Exit-status of [ abc = def ] is:" $?

… Çıkacak:

[Hello] 'un çıkış durumu: 0       - çünkü boş olmayan bir dize doğru sayılır 
[abc = abc] ' ın 
çıkış durumu : 0   - çünkü 'abc' gerçekten 'abc' ile aynıdır. : 1             - çünkü boş dize yanlış olarak kabul edilir 
[abc = def] 'in çıkış durumu: 1   - çünkü' abc 'gerçekten' def 'den farklıdır

Bununla birlikte, bash ve diğer birçok kabuk , bu durumlarda genellikle çağırmaz /bin/[(veya /usr/bin/[) değil , bunun yerine tam olarak aynı davranışla yerleşik komutu çağırır (yalnızca performans nedenleriyle). Çağırmak için /bin/[(kabuk yerleşik vekili değil) ya yolunu açıkça belirtmeniz gerekir (örneğin /bin/[ hello ]; ]☺ olsa da dirname ile önek yapmanız gerekmez ) ya da kabuğu yerleşik bir vekil kullanmayacak şekilde yapılandırmanız gerekir (örneğin, enable -n [bash).

Not: diğer cevaplar söyleniyordu gibi, [ile ilgilidir test. Ama testaksine [, gerektirmez ]son argüman olarak (; ekstra ekleyerek ve hiç beklemediği ]kadar testbu hata iletisiyle başarısız olmasına veya yanlış sonuç döndürmek için neden olabilir argümanlar) . Ve aynı dosyaya çözebilirsiniz (örneğin bir edilir sembolik olarak ; bu durumda davranış saptırma muhtemelen tarafından uygulanmaktadır anda adlandırılan komutu analiz dahilinde / kod kendisi) veya farklı dosyalara. Zira , kabuk ayrıca, yol açıkça belirtilmediği sürece yerleşik vekili de çağırır ( ) veya bunu yapmayacak şekilde yapılandırılmışsa (/bin/test/bin/[test[test/bin/testenable -n test).

PPS: aksine testve [modern ifbir gerçek dosya asla. Kabuk (örneğin bash) sözdiziminin bir parçası: if commandA; then commandB; fi(noktalı virgül yerine newlines kullanılabilir) sıfır durumuyla commandBçıkarsa, eğer-ve-sadece-çalıştırılmaya neden olur commandA. Bu, davranışlarına mükemmel şekilde uyar testveya [onları if [ "$a" = foo ]; then …; fi (veya if test "$a" = foo; then …; fidaha az okunabilir şekilde) birleştirmeyi sağlar . Ancak, modern komut dosyaları genellikle veya [[yerine ( ki bu şekilde ) asla gerçek bir dosya değildir, ancak her zaman kabuk sözdiziminin bir parçasıdır.test[if

PPPS: Olduğu gibi man- mandosya sisteminizdeki her komut için bir makale beklemeyin . Bazı (hatta "gerçek", dosya tabanlı) komutları üzerinde Bilgisi (yani sen kesinlikle hakkında bilgi bulacaksınız yer değil sadece belirli kabuk adanmış bir makale içinde belki mevcut bazı kabuk yerleşik ins bilgi, eksik olabilir test, [, if, [[). Yine de, birçok dağılımın açık ve- manparçacıkları vardır . (Hakkında , bariz bir nedenden ötürü tanınmıyor : gibi davaları sessizce ele alması gerekiyor ; bazı dağıtımlarda (kapanmadan ) hala yardım ediyor, bazılarında ise yok.)test[--helptesta=--help; test "$a"[ --help]


3
ifUnix V6'ya kadar bir komut olduğunu unutmayın . Unix V7 (1979) Bourne kabuğuyla ( if-then-else-fiyapısıyla birlikte) ve yeni testkomutla geldi.
Stéphane Chazelas
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.