Sormak istiyorum:
Neden olduğu echo {1,2,3}
, beklenen bir davranıştır ki 1 2 3 genişletilmiş ederken echo [[:digit:]]
döner [[:digit:]]
ben tüm rakamları yazdırmak için beklenen süre 0
için 9
?
Sormak istiyorum:
Neden olduğu echo {1,2,3}
, beklenen bir davranıştır ki 1 2 3 genişletilmiş ederken echo [[:digit:]]
döner [[:digit:]]
ben tüm rakamları yazdırmak için beklenen süre 0
için 9
?
Yanıtlar:
Çünkü onlar iki farklı şey. Bu küme ayracı genişlemesine{1,2,3}
bir örnektir . Yapı genişletilir kabuk tarafından önce bile görüyor. Kullandığınızda ne olacağını görebilirsiniz :{1,2,3}
echo
set -x
$ set -x
$ echo {1,2,3}
+ echo 1 2 3
1 2 3
Gördüğünüz gibi komut echo {1,2,3}
şu şekilde genişletildi:
echo 1 2 3
Ancak, [[:digit:]]
bir olan POSIX karakter sınıfı . Verdiğiniz zaman echo
, kabuk da önce onu işler, ancak bu sefer bir kabuk küresi olarak işlenir . echo *
geçerli dizindeki tüm dosyaları yazdıracak şekilde çalıştırdığınız gibi çalışır . Ancak [[:digit:]]
herhangi bir rakamla eşleşen bir kabuk glob. Şimdi, bash'da, eğer bir kabuk küresi hiçbir şeyle eşleşmezse, kendisine genişleyecektir:
$ echo /this*matches*no*files
+ echo '/this*matches*no*files'
/this*matches*no*files
Glob bir şeyle eşleşirse, yazdırılacaktır:
$ echo /e*c
+ echo /etc
/etc
Her iki durumda da, echo
kabuğun yazdırmasını söylediği her şeyi yazdırır, ancak ikinci durumda, glob bir şeyle eşleştiği için ( /etc
) buna bir şey yazdırması söylenir.
Bu nedenle, adı tam olarak bir rakamdan oluşan (veya [[:digit:]]
eşleşecek olan) herhangi bir dosya veya dizininiz olmadığından , glob kendisine genişletilir ve elde edersiniz:
$ echo [[:digit:]]
[[:digit:]]
Şimdi, 5
aynı komutu çağırıp aynı komutu çalıştırmayı deneyin :
$ echo [[:digit:]]
5
Ve birden fazla eşleşen dosya varsa:
$ touch 1 5
$ echo [[:digit:]]
1 5
Bu, bu davranışı kapatan seçeneklerin man bash
açıklanmasında belgelenmiştir nullglob
:
nullglob
If set, bash allows patterns which match no files (see
Pathname Expansion above) to expand to a null string,
rather than themselves.
Bu seçeneği ayarlarsanız:
$ rm 1 5
$ shopt -s nullglob
$ echo [[:digit:]] ## prints nothing
$
shopt -s failglob
, zsh
veya gibi modern kabuklara benzer daha yararlı bir davranış elde etmek için bakınız fish
.
failglob
. nullglob
beklenmeyen sorunlara neden olabilir, örneğin ?
.
nullglob
desenin kabuk tarafından bir glob olarak yorumlandığını göstermek için bahsettim .
{1,2,3}
olan ayracı genişleme , onların anlamı bakılmaksızın listelenen kelimelerin genişler.
[...]
dosya adı genişletmesinde (veya joker karakter veya glob) yıldız *
ve soru işaretine benzer şekilde kullanılan bir karakter grubudur ?
. İçinde listelenen herhangi bir karakterle veya listelenmiş gibi adlandırılmış grupların üyesi olan karakterlerle eşleşir [:digit:]
. Kabukların çoğunun varsayılan davranışı, ona uyan hiçbir dosya yoksa joker karakteri olduğu gibi bırakmaktır.
(Bir joker karakteri / deseni eşleşeceği dizeler kümesine gerçekten çeviremeyeceğinizi unutmayın. Yıldız işareti herhangi bir uzunluktaki herhangi bir dizeyle eşleşebilir, bu nedenle onu içeren herhangi bir deseni genişletmek sonsuz bir dizi listesi üretecektir.)
Yani:
$ bash -c 'echo [[:digit:]]' # bash leaves it as-is
[[:digit:]]
$ zsh -c 'echo [[:digit:]]' # zsh by default complains if no match
zsh:1: no matches found: [[:digit:]]
$ touch 1 3 d i g t
$ bash -c 'echo [[:digit:]]' # now there are two matches
1 3 # note that d, i, g and t do NOT match
Ama hala:
$ bash -c 'echo {1,2,3}'
1 2 3
Her ikisi de kabuk tarafından genişletilir , çalıştırdığınız komutun ls
veya echo
veya olması önemli değildir rm
. Ayrıca, bunlardan herhangi biri alıntılanırsa, bunların genişletilmeyeceğini unutmayın:
$ bash -c 'echo "[[:digit:]]"' # even though matching files still exist
[[:digit:]]
$ bash -c 'echo "{1,2,3}"'
{1,2,3}
[[:digit:]]
geçmeden önce "genişleyecektir" echo
, bu yüzden echo
asla görmez [[:digit:]]
, sadece görür 1 3
. Çalışmakta set -x
olan gerçek komutları yazdıracak şekilde çalıştırarak bunu görebilirsiniz ( set +x
tekrar kapatmak için çalıştırın ).
echo
dosyaları aramaz, kabuk yapar echo
.
{1,2,3}
(ör {1..3}
olan bağ açılımları . Bunlar, komut yürütme önce kabuk tarafından yorumlanmaktadır.
[[:digit:]]
bir desen eşleme jetonudur, ancak bunu bu desenle eşleşen herhangi bir dosyayla birlikte kullanmıyorsunuzdur. Eşleşmesi olmayan bir kalıp eşleşmesi kullanırsanız, kendi kendine genişler:
$ echo [[:digit:]]; touch 3; echo [[:digit:]]
[[:digit:]]
3