Comment fonctionne GLOBIGNORE?

15

Selon la page de manuel de bash:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

Mais en pratique ...

$ bash --noprofile --norc
bash-4.2$ touch .bar
bash-4.2$ echo .*
. .. .bar
bash-4.2$ GLOBIGNORE=.
bash-4.2$ echo .*
.bar

Pourquoi est-il ..supprimé de la liste des correspondances? Pour autant que je sache, le motif .ne correspond PAS .., n'est-ce pas?

Ernest A
la source

Réponses:

14

Faites défiler vers le bas

Les noms de fichiers .et ..sont toujours ignorés lorsque GLOBIGNOREest défini et non null.

La plupart du temps, il n'est pas souhaitable d'inclure .et ..de correspondances génériques, car ils ne représentent pas des fichiers dans le répertoire - ce sont des hacks pour faire fonctionner la navigation dans le répertoire. En fait, l'origine des fichiers dot est un bogue dans une première version de la lscommande . L'auteur voulait exclure .et ..de la liste, mais a accidentellement exclu tous les fichiers qui commencent par .. Ainsi, les fichiers de points sont devenus cachés ls. Les obus ont emboîté le pas en cachant les fichiers dot comme ls. Cependant, la façon dont cela a été fait était à nouveau un hack: les fichiers commençant par .ne sont exclus que si le point ne correspond pas explicitement dans le modèle. Ainsi, le modèle .*comprend .et ...

Pour préserver la compatibilité avec les scripts existants, les shells modernes incluent toujours .et ..(à l'exception de zsh, qui sur ce problème, comme beaucoup d'autres, a un comportement plus sain mais pas rétrocompatible). Cependant, si vous définissez GLOBIGNORE, vous utilisez une fonctionnalité spécifique à bash, qui montre que vous n'êtes pas intéressé par la compatibilité descendante. Ainsi, la correspondance des motifs change pour exclure .et ..de toutes les correspondances de motifs.

Le paramètre GLOBIGNORE=.exclut un fichier qui est de toute façon automatiquement exclu chaque fois qu'il GLOBIGNOREest défini, il est donc équivalent à shopt -s dotglobsauf cela .et ..est en outre exclu de tous les modèles.

Gilles 'SO- arrête d'être méchant'
la source
1
En fait, je viens de réaliser que le paramétrage GLOBIGNOREignore uniquement .et ..dans des modèles sans barre oblique et que GLOBIGNORE filtre les chemins de fichier et non les noms de fichier. GLOBIGNORE=.; echo .*n'inclura pas .ni .., mais GLOBIGNORE=.; echo ./.*(ou echo /bin/.*) le fera! Pour ignorer .et ..de tous les globes, il semble que vous ayez besoin de shopt -s extglobet GLOBIGNORE='?(*/)@(.|..)'.
Stéphane Chazelas
1
En fait, non, GLOBIGNORE='?(*/)@(.|..)'ne parviendrait pas à exclure .et ..à .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)'briserait des globes comme ./*...
Stéphane Chazelas
3

Extrait de la section intitulée "Expansion du nom de chemin" dans man bash:

Les noms de fichiers ''. '' Et '' .. '' sont toujours ignorés lorsque GLOBIGNORE est défini et non null.

John1024
la source