Lütfen birisi bash betikleri arasındaki -eqve ==içindeki farkı açıklayabilir mi?
Aşağıdakiler arasında herhangi bir fark var mı?
[ $a -eq $b ]
ve [ $a == $b ]
Bu sadece ==değişkenler sayı içerdiğinde mi kullanılır?
Lütfen birisi bash betikleri arasındaki -eqve ==içindeki farkı açıklayabilir mi?
Aşağıdakiler arasında herhangi bir fark var mı?
[ $a -eq $b ]
ve [ $a == $b ]
Bu sadece ==değişkenler sayı içerdiğinde mi kullanılır?
Yanıtlar:
Bunun tam tersi: =ve ==dizi karşılaştırmaları içindir, -eqsayısal olanlar içindir. -eqaynı aileden olduğu -lt, -le, -gt, -ge, ve -nebu size hangisinin hangisi hatırlamıyorum yardımcı olur.
==bu arada, bir bash-ism. POSIX kullanmak daha iyidir =. Bash'de ikisi eşdeğerdir ve düz olarak sh =, çalışması garantili tek kişidir.
$ a=foo
$ [ "$a" = foo ]; echo "$?" # POSIX sh
0
$ [ "$a" == foo ]; echo "$?" # bash specific
0
$ [ "$a" -eq foo ]; echo "$?" # wrong
-bash: [: foo: integer expression expected
2
(Yan not: Bu değişken genişletmeleri alıntılayın! Yukarıdaki çift tırnak işaretlerini atlamayın.)
Bir #!/bin/bashkomut dosyası yazıyorsanız, onun yerine kullanmanızı[[ öneririm . İkiye katlanmış formda daha fazla özellik, daha doğal sözdizimi ve sizi ayağa kaldıracak daha az sorun vardır. $aBiri için artık çift tırnak işareti gerekmez :
$ [[ $a == foo ]]; echo "$?" # bash specific
0
Ayrıca bakınız:
[[ $var = $pattern ]]aksi takdirde yerine değişmez dize olarak yorumlanmalıdır bir fnmatch deseni olarak yorumlanabilir ne isterseniz. Dizenin foogerçek olmayan bir yorumu yoktur, bu da tırnak işaretlerini tamamen güvenli hale getirir; sadece OP eşleştirmek isterse foo*(örneğin yıldız işaretiyle, dizeden sonra gelebilecek hiçbir şey anlamına gelmez foo) tırnak işaretleri veya kaçış gerekli olacaktır.
[[bir bashizm olan içindeki alıntı yapılmamış genişlemelerle ilgili bir itirazdı (yanıta +1 vermemenizin tek nedeninin bu olduğunu gösterir).
[ ... ]ve çift eşittir ==. : - /
Operatörün etrafındaki Test Yapısına bağlıdır . Seçenekleriniz çift parantez, çift parantez, tek parantez veya test şeklindedir
Eğer kullanırsanız ((...)) , sizinle aritmetik eşitlik test ediyoruz ==C olarak:
$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1
(Not: Unix anlamında ve sıfır olmayan bir testin başarısız olduğu 0anlamına gelir true)
-eqÇift parantez içinde kullanmak bir sözdizimi hatasıdır.
Eğer kullanıyorsanız [...] (veya tek ayracı) ya da [[...]] (veya çift ayracı) ya da test, sen -eq, -ne, -Bu, -le, -gt birini kullanabilir veya aritmetik karşılaştırma olarak -ge .
$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0
==Tek veya çift süslü (veya iç testkomutunun) biridir dize karşılaştırma operatörleri :
$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1
Bir dize operatörü olarak, =eşdeğerdir ==ve çevresinde boşluk not =ya ==da gerektiriyordu.
Eğer iken edebilirsiniz yapmak [[ 1 == 1 ]]ya [[ $(( 1+1 )) == 2 ]]da dize eşitliğinin test ediyor - değil aritmetik eşitlik.
Dolayısıyla , RH bir dize olmasına ve sonunda bir boşluğa sahip olmasına rağmen, büyük olasılıkla tamsayı değerinin eşit olması beklenen -eqsonucu üretir :1+12
$ [[ $(( 1+1 )) -eq "2 " ]]; echo $?
0
Aynı şeyin bir dize karşılaştırması sondaki boşluğu alır ve bu nedenle dize karşılaştırması başarısız olur:
$ [[ $(( 1+1 )) == "2 " ]]; echo $?
1
Ve hatalı bir dizi karşılaştırması tamamen yanlış cevabı verebilir. '10' sözlükbilimsel olarak '2'den küçüktür, bu nedenle bir dize karşılaştırması trueveya döndürür 0. Pek çok kişi bu böcek tarafından ısırıldı:
$ [[ 10 < 2 ]]; echo $?
0
aritmetik olarak 2'den küçük 10 için doğru teste kıyasla:
$ [[ 10 -lt 2 ]]; echo $?
1
Yorumlarda, dizelerde tamsayı kullanmanın teknik nedeni -eqile aynı olmayan dizeler için True döndüren bir soru vardır :
$ [[ "yes" -eq "no" ]]; echo $?
0
Bunun nedeni, Bash'in türsüz olmasıdır . -eqDizeleri tamsayı olarak yorumlanır neden olur mümkünse taban dönüşüm dahil:
$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0
Ve 0Bash bu sadece bir dizedir düşünürse:
$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1
Yani [[ "yes" -eq "no" ]]eşdeğerdir[[ 0 -eq 0 ]]
Son not: Test Yapılarına yönelik Bash'e özgü uzantıların çoğu POSIX değildir ve bu nedenle diğer kabuklarda başarısız olur. Diğer mermiler genellikle [[...]]ve ((...))veya desteklemez== .
[[ "yes" -eq "no" ]]doğru döndüren. Bash bu dizeleri karşılaştırılabilecek tam sayı değerlerine nasıl zorlar? ;-)
==kod örneklerinde gösteriliyor (taşınabilir değil) ve altında yalnızca (taşınabilir, standartlaştırılmış) bahsediliyor =.
==için bash'a özgü bir takma addır =ve sayısal bir karşılaştırma yerine bir dizge (sözcüksel) karşılaştırması gerçekleştirir. eqtabii ki sayısal bir karşılaştırma.
Son olarak, genellikle formu kullanmayı tercih ediyorum if [ "$a" == "$b" ]
==burada da sadece kötü biçimidir =POSIX tarafından belirlenir.
==o zaman arasına koyun [[ve ]]. (Ve betiğinizin ilk satırının kullanmayı belirttiğinden emin olun /bin/bash.)
Çocuklar: Birkaç cevap tehlikeli örnekler gösteriyor. OP'nin örneği [ $a == $b ]özellikle alıntılanmamış değişken ikamesi kullandı (Ekim '17 düzenlemesinden itibaren). İçin [...]bu dize eşitlik için güvenlidir.
Ancak [[...]], gibi alternatifleri sıralayacaksanız , sağ taraftan alıntı yapılması gerektiğini de bildirmelisiniz. Alıntı yapılmamışsa, bu bir model eşleşmesidir! (Bash man sayfasından: "Desenin herhangi bir bölümü, onu bir dizge olarak eşleşmeye zorlamak için alıntılanabilir.").
Burada bash'de, "evet" sonucunu veren iki ifade örüntü eşleştirmedir, diğer üçü dizge eşitliğidir:
$ rht="A*"
$ lft="AB"
$ [ $lft = $rht ] && echo yes
$ [ $lft == $rht ] && echo yes
$ [[ $lft = $rht ]] && echo yes
yes
$ [[ $lft == $rht ]] && echo yes
yes
$ [[ $lft == "$rht" ]] && echo yes
$
[ "$lht" = "$rht" ] tırnak eşitlik için güvenilir bile olmak. Eğer oluşturulmuş bir dosyanız varsa touch 'Afoo -o AB', [ $lft = $rht ]bu dosya adı olduğu halde, gerçek dönecektir hiç değil dizisidir AB.
[[bir bütün olarak , bash'ın (ve diğer birçok kabuğun) benimsediği 1980'lerden kalma bir ksh- izm'dir . Eğer varsa - Bütün mesele olduğunu[[hiç , o zaman güvenli bir şekilde tüm uzantılar (etrafına uygulanan KSh varsayabilirizfnmatch()tarzı desen eşleştirme, ile ERE düzenli ifadeler=~ve evet, dize bölünme bastırılması ve dosya sistemi globbing) olacaktır mevcut. Bir[[bütün olarak POSIX olmayan sözdizimi olduğundan, birlikte doğduğu özelliklerin mevcut olacağı varsayılırken ek taşınabilirlik kaybı olmaz.