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 0iç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 0iç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}echoset -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, echokabuğ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, 5aynı 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 bashaçı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, zshveya gibi modern kabuklara benzer daha yararlı bir davranış elde etmek için bakınız fish.
failglob. nullglobbeklenmeyen sorunlara neden olabilir, örneğin ?.
nullglobdesenin 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 lsveya echoveya 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 echoasla görmez [[:digit:]], sadece görür 1 3. Çalışmakta set -xolan gerçek komutları yazdıracak şekilde çalıştırarak bunu görebilirsiniz ( set +xtekrar kapatmak için çalıştırın ).
echodosyaları 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