GNU/Linux >> Linux Esercitazione >  >> Linux

Perché [a-z] corrisponde alle lettere minuscole in Bash?

In tutte le shell di cui sono a conoscenza, rm [A-Z]* rimuove tutti i file che iniziano con una lettera maiuscola, ma con bash rimuove tutti i file che iniziano con una lettera.

Poiché questo problema esiste su Linux e Solaris con bash-3 e bash-4, non può essere un bug causato da un buggy pattern matcher in libc o da una definizione locale non configurata correttamente.

Questo comportamento strano e rischioso è inteso o è solo un bug che non è stato risolto da molti anni?

Risposta accettata:

Tieni presente che quando utilizzi espressioni di intervallo come [a-z], potrebbero essere incluse lettere dell'altro caso, a seconda dell'impostazione di LC_COLLATE.

LC_COLLATE è una variabile che determina l'ordine di confronto utilizzato quando si ordinano i risultati dell'espansione del percorso e determina il comportamento delle espressioni di intervallo, delle classi di equivalenza e delle sequenze di confronto all'interno dell'espansione del percorso e della corrispondenza del modello.

Considera quanto segue:

$ 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

Nota quando il comando echo [a-z] viene chiamato, l'output previsto sarà di tutti i file con caratteri minuscoli. Inoltre, con echo [A-Z] , sono previsti file con caratteri maiuscoli.

Fascicolazioni standard con locali come en_US avere il seguente ordine:

aAbBcC...xXyYzZ
  • Tra a e z (in [a-z] ) sono TUTTE lettere maiuscole, ad eccezione di Z .
  • Tra A e Z (in [A-Z] ) sono TUTTE lettere minuscole, ad eccezione di a .

Vedi:

     aAbBcC[...]xXyYzZ
     |              |
from a      to      z

     aAbBcC[...]xXyYzZ
      |              |
from  A     to       Z

Se modifichi il LC_COLLATE variabile in C sembra come previsto:

$ export LC_COLLATE=C
$ echo [a-z]
a b c x y z
$ echo [A-Z]
A B C X Y Z

Quindi, non è un bug , è un problema di confronto .

Invece delle espressioni di intervallo puoi usare classi di caratteri definite POSIX, come upper o lower . Funzionano anche con diversi LC_COLLATE configurazioni e anche con caratteri accentati :

$ echo [[:lower:]]
a b c x y z à è é
$ echo [[:upper:]]
A B C X Y Z

Linux
  1. Cosa fa "exec {fd}/watchdog" in Bash?

  2. Perché la sostituzione del processo Bash non funziona con alcuni comandi?

  3. Perché Sudo ignora gli alias?

  4. Perché non posso usare Cd in uno script Bash??

  5. Perché la Regex in Bash funziona solo se è una variabile e non direttamente??

Perché `esce &` non funziona?

Bash:perché lo script genitore non termina su SIGINT quando lo script figlio intercetta SIGINT?

La corrispondenza del modello non funziona nello script bash

Perché Bash `(())` non funziona all'interno di `[[]]`?

Perché il mio $LD_LIBRARY_PATH viene disattivato quando utilizzo screen con bash?

In che modo bash verifica "false"?