Soru Bash çift ve tek köşeli parantez arasındaki fark nedir?


Sadece aradaki farkın ne olduğunu merak ettim

[[ $STRING != foo ]]

ve

[ $STRING != foo ]

Bunun dışında, sonuncusu posix uyumludur, sh içinde bulunur ve eski bash içinde bulunan bir uzantıdır.


347
2017-08-09 21:11


Menşei


Ayrıca, hiç parantez kullanmayı düşünmüyorsanız, örn. bağlamında if ifade, bkz. mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D - Kev
Ayrıca, Ubuntu'nun dokümanlarından: wiki.ubuntu.com/... - radistao


Cevaplar:


Birkaç fark var. Benim düşünceme göre, en önemlilerinden bazıları:

  1. [ Bash ve diğer birçok modern kabuklarda yerleşiktir. Yerleşik [ benzer test kapanış ek zorunluluk ile ]. Yerleşikler [ ve test işlevselliği taklit /bin/[ ve /bin/test kendi sınırlamaları ile birlikte, komut dosyalarının geriye dönük olarak uyumlu olmasını sağlayın. Orijinal yürütücüler daha çok POSIX uyumluluğu ve geriye dönük uyumluluk için hala mevcut. Komutu çalıştırmak type [ Bash bunu gösterir [ varsayılan olarak bir yerleşik olarak yorumlanır. (Not: which [ sadece çalıştırılabilirleri arar YOL ve eşdeğerdir type -p [)
  2. [[ uyumlu değil, mutlaka ne olursa olsun /bin/sh noktalar. Yani [[ daha modern Bash / Zsh / Ksh seçeneğidir.
  3. Çünkü [[ kabuğun içine yerleştirilmiştir ve eski gereksinimlere sahip değildir, kelime bölme hakkında endişelenmenize gerek yoktur. IFS boşluklu bir dizgeye değerlendiren değişkenlere karmak için değişken. Bu nedenle, değişkeni çift tırnak içine almanız gerekmez.

Çoğunlukla, geri kalanı sadece güzel bir sözdizimi. Daha fazla fark görmek için bu bağlantıyı bir SSS yanıtına öneririm: Test arasındaki fark nedir, [ve [[?. Aslında, bash komut dosyası hakkında ciddi iseniz, tüm okumayı öneririm wikiSSS dahil, tuzaklarve Rehber. Kılavuz bölümünden test bölümü Bu farklılıkları ve yazar (lar) ın neden düşündüğünü açıklar. [[ taşınabilir olmak konusunda endişelenmenize gerek yoksa daha iyi bir seçimdir. Ana nedenler:

  1. Testin sol tarafına alıntı yapmaktan endişe etmenize gerek yok, böylece gerçekten bir değişken olarak okunur.
  2. Daha az ve daha büyük kaçmak zorunda değilsiniz < > Onları, dosyaların üzerine yazarak bazı şeyleri karıştırabilen, giriş yönlendirmesi olarak değerlendirilmemelerini sağlamak için ters eğik çizgi ile. Bu yine geri gider [[ yerleşik olmak. [(Test) harici bir program ise, kabuk değerlendirildiği şekilde bir istisna yapmak zorunda kalacaktır. < ve > Yalnızca /bin/test gerçekten mantıklı olmayacak deniyor.

262
2017-08-09 21:56



Teşekkürler, bash SSS ile ilgili bağlantı aradığım şeydi (bu sayfa hakkında bilgi sahibi olmadı, teşekkürler). - 0x89
Yayınınızı bu bilgilerle düzenledim, ancak [ve testler yerleşik olarak yürütüldü. Yerleşikler, / bin / [/ / / / / / / / yerine geçmek için tasarlandılar, ancak ikili dosyaların sınırlarını çoğaltmak için de gerekliydi. 'Type [' komutu, yerleşimin kullanıldığını doğrular. 'hangi [' sadece PATH üzerinde çalıştırılabilirleri arar ve '-P [' türüne eşdeğerdir - klynch


Kısacası:

[bir bash yerleşik

[[]] bash Anahtar kelimeler

Anahtar Kelimeler: Anahtar kelimeler yapıtaşları gibidir, ancak asıl fark, onlara özel ayrıştırma kurallarının uygulanmasıdır. Örneğin, [[bir bash anahtardır] iken [[bir bash anahtardır. Her ikisi de bir şeyleri test etmek için kullanılırlar, ancak [[bir yerleşik yerine bir anahtar kelime olduğu için, onu çok daha kolay hale getiren birkaç özel ayrıştırma kuralından yararlanır:

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

İlk örnek bir hata döndürür çünkü bash, b dosyasını [a] komutuna yönlendirmeyi dener. İkinci örnek aslında beklediğiniz şeyi yapar. <Karakteri artık Dosya Yönlendirme operatörünün özel anlamlarına sahip değil.

Kaynak: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments


110
2017-12-29 19:42



[ bir POSIX kabuk komutudur; yerleşik olması gerekmez. ] sadece bu komutun aradığı bir argümandır, böylece sözdizimi dengeli olur. Komut bir eşanlamıdır test bunun haricinde test kapanışa bakmıyor ]. - Kaz
Buraya bakın: pubs.opengroup.org/onlinepubs/009695399/utilities/test.html - Kaz


Davranış farklılıkları

Bash 4.3.11'de test edilmiştir:

  • POSIX vs Bash uzantısı:

    • [  POSIX
    • [[ Bash uzantısıdır
  • sihir vs düzenli komut

    • [ sadece garip bir isimle normal bir komuttur.

      ] sadece bir argüman [ Bu, başka argümanların kullanılmasını engeller.

      Ubuntu 16.04 aslında bunun için bir yürütülebilir /usr/bin/[ coreutils tarafından sağlanan, ancak bash yerleşik sürümü önceliğe sahiptir.

      Bash'in komutu ayrıştırdığı şekilde hiçbir şey değişmez.

      Özellikle, < yönlendirme, && ve || çoklu komutları birleştirmek, ( ) tarafından kaçmadıkça alt kuşaklar oluşturur \ve kelime genişletme her zamanki gibi gerçekleşir.

    • [[ X ]] tek bir yapıdır X büyülü olarak ayrıştırılabilir. <, &&, || ve () özel olarak ele alınır ve kelime bölme kuralları farklıdır.

      Gibi başka farklılıklar da var = ve =~.

    Bashese'de: [ yerleşik bir komuttur ve [[ bir anahtar kelimedir: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • && ve ||

    • [[ a = a && b = b ]]: Doğru, mantıklı ve
    • [ a = a && b = b ]: sözdizimi hatası, && AND komut ayırıcı olarak ayrıştırıldı cmd1 && cmd2 
    • [ a = a -a b = b ]: eşdeğer, ancak POSIX tarafından kullanımdan kaldırıldı
    • [ a = a ] && [ b = b ]: POSIX önerisi
  • (

    • [[ (a = a || a = b) && a = b ]]: yanlış
    • [ ( a = a ) ]: sözdizimi hatası, () bir alt kabuk olarak yorumlanır
    • [ \( a = a -o a = b \) -a a = b ]: eşdeğer ama () POSIX tarafından kullanımdan kaldırıldı
    • ([ a = a ] || [ a = b ]) && [ a = b ] POSIX önerisi
  • kelime bölme

    • x='a b'; [[ $x = 'a b' ]]: Doğru, gerekli değildir
    • x='a b'; [ $x = 'a b' ]: sözdizimi hatası, genişler [ a b = 'a b' ]
    • x='a b'; [ "$x" = 'a b' ]: eşdeğer
  • =

    • [[ ab = a? ]]: Doğru, çünkü desen eşleştirmesi (* ? [ sihirdir). Küre, geçerli dizindeki dosyalara genişletilmez.
    • [ ab = a? ]: a? glob genişler. Geçerli dizindeki dosyalara bağlı olarak doğru veya yanlış olabilir.
    • [ ab = a\? ]: yanlış, glob genişlemesi değil
    • = ve == her ikisinde de aynı [ ve [[, fakat == Bash uzantısıdır.
    • printf 'ab' | grep -Eq 'a.': POSIX ERE eşdeğeri
    • [[ ab =~ 'ab?' ]]: yanlış, büyü ile kaybeder ''
    • [[ ab? =~ 'ab?' ]]: doğru
  • =~

    • [[ ab =~ ab? ]]: true, POSIX genişletilmiş düzenli ifade maç, ? genişlemiyor glob
    • [ a =~ a ]: sözdizimi hatası
    • printf 'ab' | grep -Eq 'ab?': POSIX eşdeğeri

Tavsiye

Her zaman kullanmayı tercih ederim [].

Her biri için POSIX eşdeğeri var [[ ]] Gördüğüm yapı.

Eğer kullanırsan [[ ]] sen:

  • taşınabilirliği kaybet
  • okuyucuyu başka bir bash uzantısının inceliklerini öğrenmeye zorlar. [sadece garip bir isimle düzenli bir komuttur, özel bir semantik yoktur.

63
2017-07-12 10:22



Nasıl kullanılır printf 'ab' | grep -Eq 'ab?' içinde if [ … ]? - meeDamian
@meeDamian if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi. [] sadece bir komut gibidir grep. () o komutta gerekli olmayabilir. Emin değilim: |Bash'in işleri nasıl ayrıştırdığına bağlı. Eğer yoktu | Eminim yazabilirsin if cmd arg arg; then. - Ciro Santilli 新疆改造中心 六四事件 法轮功
@meeDamian evet, gerek yok () görünüyor: stackoverflow.com/questions/8965509/... - Ciro Santilli 新疆改造中心 六四事件 法轮功
Güzel liste! Ayrıca bakınız: wiki.ubuntu.com/... - radistao


Manpage'in ilgili bölümlerinin hızlı bir şekilde okunmasına dayanan temel fark, == ve != operatörler, bir harf dizisinden ziyade bir modelle eşleşir ve ayrıca =~ regex karşılaştırma operatörü.


4
2017-08-09 21:17





Tek Braketi diğer bir deyişle [] Koşullu bir ifadeyi kapatmak için POSIX kabuğuna uyumludur.

Çift parantez diğer bir deyişle [[]] standart POSIX sürümü geliştirilmiş (veya uzantısı) bir sürümüdür, bu bash ve diğer kabuklar (zsh, ksh) tarafından desteklenmektedir.

Bash olarak, sayısal karşılaştırma için kullanırız eq, ne,lt ve gt, karşılaştırma için çift köşeli parantez ile kullanabiliriz ==, !=, <, ve > harfi harfine.

  • [ test komutu için eşanlamlıdır. Kabuğa inşa edilmiş olsa bile, yeni bir süreç yaratır.
  • [[ bir program değil, bir anahtar kelime olan yeni geliştirilmiş bir sürümüdür.

Örneğin:

[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory 
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works

3
2018-02-08 03:15