Bunun için iyi bir neden yok
[[ $a = a|b ]]
$ a|bA'nın dize olup olmadığını sınamak yerine bir hata bildirmesi gerekirken [[ $a =~ a|b ]]hata döndürmez.
Bunun tek nedeni |genellikle (dış ve iç [[ ... ]]) özel bir karakter olmasıdır. Bu [[ $a =konumda, normal bir kabuk komut satırındaki argümanlar veya yeniden yönlendirme hedefleri gibi bashnormal bir WORD olan bir simge türü bekler (ancak extglobseçenek bash 4.1'den beri etkinleştirilmiş gibi).
(tarafından WORD burada, ben bir atıfta kelime gibi bir varsayımsal kabuk dilbilgisi POSIX şartnamenin açıklanana kabuk, basit bir kabuk komut satırında simge biri İngilizce gibi kelimelerin değil başka tanım olarak ayrıştırmak olacağı bir şey olduğunu, bir harf dizisinden biri veya boşluk bırakmayan karakter dizisi. foo"bar baz", $(echo x y)bu tür iki WORD'dür ).
Normal bir kabuk komut satırında:
echo a|b
Is echo ayöneltilen b. a|bbir WORD değil , üç jeton: bir a WORD , bir |jeton ve bir b WORD jetonu.
İçinde kullanıldığında [[ $a = a|b ]], aldığı bashbir WORD bekler ( a), ancak |hataya neden olan beklenmedik bir belirteç bulur .
İlginçtir, bashşikayet etmiyor:
[[ $a = a||b ]]
Artık bir ajeton, ardından bir jeton ve ardından bir ||jeton olduğundan b, şu şekilde aynı şekilde ayrıştırıldı:
[[ $a = a || b ]]
Hangi yani test ediyor $aolduğunu aveya bdize olmayan boşaltın.
Şimdi:
[[ $a =~ a|b ]]
bashaynı ayrıştırma kuralına sahip olamaz. Aynı ayrıştırma kuralına sahip olmak, yukarıdakilerin bir hata vereceği ve tek bir WORD| olduğundan emin olmak için teklif vermesi gerektiği anlamına gelir . Ancak, bash 3.2'den beri, yaparsanız:a|b
[[ $a =~ 'a|b' ]]
Bu artık a|bnormal ifadeyle değil , normal ifadeyle eşleşiyor a\|b. Yani, kabuk alıntılamanın normal ifade operatörlerinin özel anlamını kaldırmanın yan etkisi vardır. Bu bir özelliktir, bu nedenle davranış [[ $a = "?" ]]bire benzer , ancak joker karakter kalıpları (içinde kullanılır [[ $a = pattern ]]) kabuk WORDS (örneğin globlarda kullanılır), regexps ise değildir.
Yani bashbaşka türlü normal gibi özel kabuk karakterler tüm genişletilmiş regexp'in operatörleri tedavi etmek vardır |, (, )bir argüman ayrıştırma farklı zaman =~operatör.
Yine de,
[[ $a =~ (ab)*c ]]
şimdi çalışıyor,
[[ $a =~ [)}] ]]
yapmaz. Gerekenler:
[[ $a =~ [\)}] ]]
[[ $a =~ [')'}] ]]
Hangi önceki sürümlerinde bashters eğik çizgi üzerinde yanlış eşleşir. Bu düzeltildi, ama
[[ $a =~ [^]')'] ]]
Does değil o mesela gerektiği gibi ters eğik çizgi üzerinde uyuyor. Çünkü bashfarkına başarısız )yüzden kaçar, parantez içinde olduğuna )bir sonuçlanması [^]\)]regexp herhangi karakteri ama üzerinde maçları ], \ve ).
ksh93 o cephede çok daha kötü hatalar var.
Bu zshnormal bir kabuk kelimesidir ve normal ifade operatörlerinden alıntı yapmak normal ifade operatörlerinin anlamını etkilemez.
[[ $a =~ 'a|b' ]]
a|bNormal ifade ile eşleşiyor .
Bu =~, [/ testkomutuna da eklenebileceği anlamına gelir :
[ "$a" '=~' 'a|b' ]
test "$a" '=~' 'a|b'
(ayrıca çalışır yash. Burada özel bir kabuk operatörü olarak =~belirtilmesi gerekir ).zsh=something
bash 3.1 eskiden böyle davranıyordu zsh. Muhtemelen hizalamak için 3.2'de değişti ksh93( bashilk ortaya çıkan kabuk olmasına rağmen [[ =~ ]]), ancak yine de yapabilir BASH_COMPAT=31veya shopt -s compat31önceki davranışa geri dönebilirsiniz (ancak 3.1'de [[ $a =~ a|b ]]bir hata döndürecek basholsa da, artık içinde bash -O compat31daha yeni versiyonları ile bash).
Umarım neden kuralların kafa karıştırıcı olduğunu ve neden kullandığımı açıklar:
[[ $a =~ $var ]]
diğer mermilere taşınabilirlik dahil yardımcı olur.
|özel olduğu yerde ) varsayılan olarak sağ tarafında açık olduğunu unutmayın[[ $var = $pattern ]].shoptBu davranışın görüldüğü sürümleri ve seçenek yapılandırmalarını izole etmek ilginç olacaktır - eğer sadeceextglobvarsayılan veya açık yapılandırma ile açıksa, oradayız.