GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi [a-z] correspond-il aux lettres minuscules dans Bash ?

Dans tous les shells que je connais, rm [A-Z]* supprime tous les fichiers commençant par une lettre majuscule, mais avec bash, cela supprime tous les fichiers commençant par une lettre.

Comme ce problème existe sur Linux et Solaris avec bash-3 et bash-4, il ne peut pas s'agir d'un bogue causé par un comparateur de modèle bogué dans la libc ou une définition de paramètres régionaux mal configurée.

Ce comportement étrange et risqué est-il intentionnel ou s'agit-il simplement d'un bug non corrigé depuis de nombreuses années ?

Réponse acceptée :

Notez que lors de l'utilisation d'expressions de plage telles que [a-z], des lettres de l'autre casse peuvent être incluses, selon le paramètre de LC_COLLATE.

LC_COLLATE est une variable qui détermine l'ordre de classement utilisé lors du tri des résultats de l'expansion des noms de chemin et détermine le comportement des expressions de plage, des classes d'équivalence et des séquences d'assemblage dans l'expansion des noms de chemin et la correspondance des modèles.

Considérez ce qui suit :

$ 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

Remarquez quand la commande echo [a-z] est appelée, la sortie attendue serait tous les fichiers avec des caractères minuscules. Aussi, avec echo [A-Z] , des fichiers avec des caractères majuscules seraient attendus.

Classements standard avec des paramètres régionaux tels que en_US avoir l'ordre suivant :

aAbBcC...xXyYzZ
  • Entre a et z (en [a-z] ) sont TOUTES des lettres majuscules, à l'exception de Z .
  • Entre A et Z (en [A-Z] ) sont TOUTES des lettres minuscules, à l'exception de a .

Voir :

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

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

Si vous modifiez le LC_COLLATE variable en C il ressemble à ce que nous attendions :

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

Donc, ce n'est pas un bug , c'est un problème de classement .

Au lieu d'expressions de plage, vous pouvez utiliser des classes de caractères définies par POSIX, telles que upper ou lower . Ils fonctionnent également avec différents LC_COLLATE configurations et même avec des caractères accentués :

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

Linux
  1. Est-ce que ~ est toujours égal à $home ?

  2. Pourquoi la substitution de processus Bash ne fonctionne-t-elle pas avec certaines commandes ?

  3. Pourquoi Sudo ignore-t-il les alias ?

  4. Pourquoi ne puis-je pas utiliser Cd dans un script Bash ? ?

  5. Pourquoi `exit &` ne fonctionne pas ?

Pourquoi le Regex dans Bash ne fonctionne-t-il que s'il s'agit d'une variable et pas directement ? ?

Bash :Pourquoi le script parent ne se termine-t-il pas sur SIGINT lorsque le script enfant piège SIGINT ?

La correspondance de modèle ne fonctionne pas dans le script bash

Pourquoi Bash `(())` ne fonctionne-t-il pas dans `[[]]` ?

Pourquoi Ctrl + V ne colle-t-il pas dans Bash (shell Linux) ?

pourquoi supprimer l'historique bash n'est pas suffisant?