Como o GLOBIGNORE funciona?


15

De acordo com a página de manual do 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.

No entanto, na prática ...

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

Por que é ..removido da lista de correspondências? Até onde eu sei, o padrão .NÃO corresponde .., não é?

Respostas:


14

Role para baixo

Os nomes de arquivos .e ..sempre são ignorados quando GLOBIGNOREdefinidos e não nulos.

Na maioria das vezes, não é desejável incluir .e ..como correspondências curinga, pois eles não representam arquivos dentro do diretório - são hacks para fazer a navegação no diretório funcionar. De fato, a origem dos arquivos de ponto é um bug em uma versão anterior do lscomando . O autor pretendia excluir .e ..da lista, mas excluiu acidentalmente todos os arquivos que começaram com .. Assim, os arquivos de ponto ficaram ocultos ls. Os shells seguiram o exemplo, ocultando arquivos de pontos como ls. No entanto, a maneira como isso foi feito foi novamente um hack: os arquivos iniciados com .serão excluídos apenas se o ponto não corresponder explicitamente ao padrão. Portanto, o padrão .*inclui .e ...

Para preservar a compatibilidade com scripts existentes, os shells modernos ainda incluem .e ..(exceto o zsh, que nesta questão, como muitos outros, tem um comportamento mais saudável, mas não compatível com versões anteriores). No entanto, se você definir GLOBIGNORE, você está usando um recurso específico do bash, que mostra que não está interessado em compatibilidade com versões anteriores. Portanto, a correspondência de padrão é alterada para excluir .e ..de todas as correspondências de padrão.

Definir GLOBIGNORE=.exclui um arquivo que é excluído automaticamente de qualquer maneira, sempre que GLOBIGNOREfor definido, por isso é equivalente a shopt -s dotglobexceto que .e ..além disso são excluídos de todos os padrões.


1
Na verdade, acabei de perceber que a configuração GLOBIGNOREapenas ignora .e ..em padrões sem barra, e o GLOBIGNORE filtra os caminhos de arquivos e não os nomes de arquivos. GLOBIGNORE=.; echo .*não incluirá .nem .., mas GLOBIGNORE=.; echo ./.*(ou echo /bin/.*) incluirá! Para ignorar .e ..de todos os globs, parece que você precisa shopt -s extglobe GLOBIGNORE='?(*/)@(.|..)'.
Stéphane Chazelas

1
Na verdade, não, GLOBIGNORE='?(*/)@(.|..)'não seria suficiente para excluir .e ..no .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)'quebraria globs como ./*...
Stéphane Chazelas

3

Na seção intitulada "Expansão do nome do caminho" em man bash:

Os nomes de arquivo ''. '' E '' .. '' sempre são ignorados quando GLOBIGNORE é definido e não nulo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.