Di semua shell yang saya ketahui, rm [A-Z]* menghapus semua file yang dimulai dengan huruf besar, tetapi dengan bash ini menghapus semua file yang dimulai dengan huruf.
Karena masalah ini ada di Linux dan Solaris dengan bash-3 dan bash-4, itu tidak mungkin merupakan bug yang disebabkan oleh pencocokan pola kereta di libc atau definisi lokal yang salah dikonfigurasi.
Apakah perilaku aneh dan berisiko ini disengaja atau hanya bug yang tidak diperbaiki sejak bertahun-tahun?
Jawaban yang Diterima:
Perhatikan bahwa saat menggunakan ekspresi rentang seperti [a-z], huruf dari kasus lain mungkin disertakan, tergantung pada setelan LC_COLLATE.
LC_COLLATE adalah variabel yang menentukan urutan susunan yang digunakan saat menyortir hasil perluasan nama jalur, dan menentukan perilaku ekspresi rentang, kelas ekuivalensi, dan urutan susunan dalam perluasan nama jalur dan pencocokan pola.
Pertimbangkan hal berikut:
$ touch a A b B c C x X y Y z Z
$ ls
a A b B c C x X y Y z Z
$ echo [a-z] # Note the missing uppercase "Z"
a A b B c C x X y Y z
$ echo [A-Z] # Note the missing lowercase "a"
A b B c C x X y Y z Z
Perhatikan ketika perintah echo [a-z] dipanggil, output yang diharapkan adalah semua file dengan karakter huruf kecil. Juga, dengan echo [A-Z] , file dengan karakter huruf besar diharapkan.
Susunan standar dengan lokal seperti en_US memiliki urutan sebagai berikut:
aAbBcC...xXyYzZ
- Antara
adanz(dalam[a-z]) adalah SEMUA huruf besar, kecualiZ. - Antara
AdanZ(dalam[A-Z]) adalah SEMUA huruf kecil, kecualia.
Lihat:
aAbBcC[...]xXyYzZ
| |
from a to z
aAbBcC[...]xXyYzZ
| |
from A to Z
Jika Anda mengubah LC_COLLATE variabel ke C terlihat seperti yang diharapkan:
$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z
Jadi, ini bukan bug , ini adalah masalah pengumpulan .
Alih-alih ekspresi rentang, Anda dapat menggunakan kelas karakter yang ditentukan POSIX, seperti upper atau lower . Mereka juga bekerja dengan LC_COLLATE yang berbeda konfigurasi dan bahkan dengan karakter beraksen :
$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z