Yanıtlar:
Arasındaki fark [[ … ]]
ve [ … ]
daha çok kaplı Bash - tek veya çift bir ayraç kullanılarak . En önemlisi, [[ … ]]
özel bir sözdizimi, oysa [
bir komut için komik görünümlü bir isim. [[ … ]]
içinde olanlar için özel sözdizimi kuralları vardır [ … ]
, değildir.
Bir joker karakterin eklenmiş kırışmasıyla, işte nasıl [[ $a == z* ]]
değerlendirilir:
[[ … ]]
koşullu ifadenin etrafındaki koşullu yapı budur $a == z*
.==
operandlarla $a
ve ikili işlecidir z*
.a
.==
İşleci değerlendirin : değişkenin değerinin a
kalıpla eşleşip eşleşmediğini test edin z*
.İşte nasıl [ $a == z* ]
değerlendirilir:
[
kelimeleri değerlendirerek oluşturduğu argüman komut $a
, ==
, z*
, ]
.$a
Değişkenin değerine genişletin a
.a
6 karakterlik dizedir foo b*
(örneğin elde edilen a='foo b*'
) ve (geçerli dizinin dosyaların listesi bar
, baz
, qux
, zim
, zum
), sonra genişleme sonucu kelimelerin aşağıdaki listesi: [
, foo
, bar
, baz
, ==
, zim
, zum
, ]
.[
önceki adımda elde edilen parametrelerle çalıştırın .
[
komut bir sözdizimi hatasından şikayet eder ve 2 durumunu döndürür.Not: [[ $a == z* ]]
3. adımda, değeri a
kelime bölme işlemine ve dosya adı oluşturulmasına maruz kalmaz, çünkü tek bir kelimenin beklendiği bir bağlamdadır (koşullu işlecin sol argümanı ==
). Çoğu durumda, tek bir kelime bu konumda mantıklıysa, değişken genişleme çift tırnak işareti gibi davranır. Bununla birlikte, bu kuralın bir istisnası vardır: içinde [[ abc == $a ]]
, a
joker karakter içeriyorsa a
, joker desenle eşleştirilir. Değeri Örneğin, a
bir a*
o [[ abc == $a ]]
doğrudur (joker çünkü *
içinde tırnaksız genişleme gelen $a
maçları *
) oysa [[ abc == "$a" ]]
(yanlıştır sıradan karakteri nedeniyle*
alıntı genişlemesinden gelen $a
eşleşmiyor bc
). İçeride [[ … ]]
, çift tırnak, bir fark yapmazlar dize eşleştirme operatörlerin sağ tarafta dışında ( =
, ==
, !=
ve =~
).
[
test
komut için bir diğer addır. Unix Versiyon 6'nın bir if
emri vardı ancak Versiyon 7 (1979) , if-then-else-elif-fi konstrüksiyonu da dahil olmak üzere birkaç programlama yapısına sahip olan yeni Bourne kabuğuyla birlikte geldi ve Unix versiyon 7 , çoğu Eski sürümlerde komut tarafından gerçekleştirilen "testler" .test
if
[
test
Unix System III (1981) 'de bir takma isim yapıldı ve her ikisi de kabuğun içine yerleştirildi . Bazı Unix varyantlarının bundan [
sonraya kadar bir emri bulunmadığı belirtilmelidir , ancak Almquist kabuğuna dayanan bazı sh
BSD'lerde 2000'li yılların başlarına kadar (bir test
yerleşik her zaman ash
kaynağa dahil edildi , ancak BSD'ler başlangıçta devre dışı bırakıldı)).
Not test
aka [
"testler" yapmak için bir komut olduğunu, eşitlik operatörü bu yüzden, bu yüzden bir atama ve eşitlik operatörü arasındaki belirsizliği giderecek hiçbir neden yok, o komut yaptığı hiçbir atama yoktur =
. ==
sadece birkaç yeni uygulama tarafından desteklenir [
(ve sadece bir takma addır =
).
Çünkü [
hiçbir şey daha bir komutla birden, o kabuk tarafından başka komutla aynı şekilde ayrıştırılır.
Spesifik olarak, örneğinizde, $a
alıntılanmadığı için, normal kelime bölme kurallarına göre birkaç kelimeye bölünür ve her kelime, muhtemelen daha fazla kelimeyle sonuçlanacak şekilde isimlendirmek için isimlendirir. [
komuta ayrı bir argüman .
Benzer şekilde, z*
şu anki dizinden başlayarak geçerli dizindeki dosya listesine genişletilecektir z
.
Yani örneğin $a
bir b* = x
ve orada z1
, z2
, b1
ve b2
geçerli dizinde dosyaları [
komut 9 argümanları alacağı: [
, b1
, b2
, =
, x
, ==
, z1
, z2
ve ]
.
[
bağımsız değişkenlerini koşullu ifade olarak ayrıştırır. Bu 9 argüman geçerli bir koşullu ifadeye eklenmez, bu nedenle büyük olasılıkla bir hata verecektir.
[[ ... ]]
Yapı muhtemelen etrafında 1988 olarak Korn kabuk tarafından tanıtıldı ksh86a
iken 1987 yılında o yoktu ksh88
baştan vardı.
Ksh (tüm uygulamalar) dışında, [[...]]
bash (sürüm 2.02'den beri) ve zsh tarafından da desteklenir, ancak üç uygulama da farklıdır ve değişiklikler genel olarak geriye dönük uyumlu olsa da aynı kabuğun her sürümü arasında farklılıklar vardır (önemli bir istisna hariç =~
Davranışı değiştiğinde belirli bir sürümden sonra birkaç komut dosyasını kırdığı bilinen operatör). [[...]]
POSIX veya Unix veya Linux (LSB) tarafından belirtilmez. Birkaç kez dahil edilmek için düşünülmüş, ancak ana mermiler tarafından desteklenen ortak işlevselliğinin zaten [
komut ve case-in-esac
yapı tarafından ele alındığı için dahil edilmemiştir .
Bütün [[ ... ]]
yapı bir emirdir. Yani, bir çıkış statüsüne sahiptir (koşullu ifadeyi değerlendirmenin sonucu olduğu için en önemli varlığıdır), onu başka bir komuta gönderebilirsiniz (faydalı olmasa da) ve genel olarak istediğiniz yerde kullanabilirsiniz. başka bir komut kullanın (yalnızca kabuğun içinde, kabuğun yapısı olduğu için), ancak normal bir basit komut gibi ayrıştırılmaz. İçindeki şey kabuklu tarafından koşullu ifade olarak ayrıştırılır ve kelime bölme ve dosya adı oluşturmanın olağan kuralları farklı uygulanır.
[[ ... ]]
==
en baştan biliyor ve =
1 ile eşdeğer . Ksh bir gaf olduğunu olsa (ve karışıklık ve birçok böcek neden olan) =
ve ==
bir eşitlik operatörü ama (gerçi bir desen eşleştirme operatörü olmayan eşleme boy alıntı ile değil kabuğuna kabuk farklılık belirsiz kurallara devre dışı bırakılabilir).
Yukarıdaki kodunuzda [[ $a == z* ]]
kabuk, alışılmış olanlara benzer kurallarda birkaç belirteçte ayrıştırır, onu bir kalıp eşleştirme karşılaştırması olarak tanır z*
, a
değişkenin içeriğiyle eşleşecek bir kalıp olarak değerlendirir .
Genelde, kendini ayaklarıyla vurmak [[ ... ]]
, [
komutta olduğundan daha zor . Ama birkaç kural gibi
-a
veya -o
operatörünü asla kullanmayın (birkaç [
komut ve &&
ve ||
kabuk operatörlerini kullanın)[
POSIX kabukları ile güvenilir olun .
[[...]]
farklı kabuklarda -nt
regexp eşleşen operatörler gibi ekstra operatörleri destekler ... ancak liste ve davranış, kabuktan kabuğa ve sürümden sürüme değişir.
Bu nedenle, betiğinizin hangi kabuk ve minimum sürümle yorumlanacağını bilmiyorsanız, standart [
komutla bağlantı yapmak muhtemelen daha güvenlidir .
1 Bir istisna: [[...]]
sürümde bash'a eklendi 2.02
. Kadar 2.03
değişti nerede, [[ x = '?' ]]
ise gerçek döneceğini [[ x == '?' ]]
return false olacaktır. Bu alıntı, =
işleci bu sürümlerde kullanırken desen eşleşmesini engellemedi , ancak kullanırken kullandı ==
.
[ '!' = foo -o a = a ]
içinde bash
mesela.
her ikisi de ifadeleri değerlendirmek için kullanılır ve [[POSIX'in eski kabuklu kabuğu ile çalışmaz ve [[ayrıca desen eşleşmesini ve regex'i destekler). örnek bunları dene
[ $n -eq 0 -a $y -eq 0 ] && echo "Error" || echo "Ok"
[[ $n -eq 0 && $y -eq 0 ]] && echo "Error" || echo "Ok"
[[...]]
bazı sürümlerin regexp'leri desteklediğini, bazı sürümlerin de [
regexp eşleşmesini desteklediğini unutmayın. Aritmetik karşılaştırma için, destekleyen mermilerde [[
yazmayı tercih edersiniz(( n == 0 && y == 0))