Jak działa GLOBIGNORE?

15

Według strony podręcznika 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.

Jednak w praktyce ...

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

Dlaczego jest ..usuwany z listy dopasowań? O ile mi wiadomo, wzór .NIE pasuje .., prawda?

Ernest A.
źródło

Odpowiedzi:

14

Przewiń w dół

Nazwy plików .i ..są zawsze ignorowane, gdy GLOBIGNOREsą ustawione, a nie null.

W większości przypadków nie jest pożądane dołączanie .i stosowanie ..znaków wieloznacznych, ponieważ nie reprezentują one plików w katalogu - są włamaniami, aby nawigacja w katalogu działała. W rzeczywistości pochodzenie plików kropek jest błędem we wczesnej wersji lspolecenia . Autor zamierzał wykluczyć .i ..z listy, ale przypadkowo wykluczył wszystkie pliki, które zaczynają się od .. W ten sposób pliki kropek zostały ukryte ls. Powłoki poszły w ich ślady, ukrywając pliki kropek takie jak ls. Jednak sposób, w jaki to zrobiono, był ponownie włamaniem: pliki zaczynające się od .są wykluczane tylko wtedy, gdy kropka nie jest wyraźnie dopasowana do wzorca. Więc wzorzec .*obejmuje .i ...

Aby zachować zgodność z istniejącymi skryptami, współczesne powłoki nadal zawierają .i ..(oprócz zsh, który w tej kwestii, podobnie jak wiele innych, ma bardziej rozsądne, ale nie kompatybilne wstecz zachowanie). Jeśli jednak ustawisz GLOBIGNORE, używasz funkcji specyficznej dla bash, która pokazuje, że nie jesteś zainteresowany kompatybilnością wsteczną. Więc zmiany dopasowania wzorca, aby wykluczyć .i ..ze wszystkich dopasowań wzorca.

Ustawienie GLOBIGNORE=.wyklucza plik, który jest i tak automatycznie wykluczany, ilekroć GLOBIGNOREjest ustawiony, więc jest równoważny z shopt -s dotglobwyjątkiem tego .i ..jest ponadto wykluczany ze wszystkich wzorców.

Gilles „SO- przestań być zły”
źródło
1
Właściwie właśnie zdałem sobie sprawę, że ustawienie GLOBIGNOREignoruj .i ..we wzorcach bez ukośników, a GLOBIGNORE filtruje ścieżki plików, a nie nazwy plików. GLOBIGNORE=.; echo .*nie będzie zawierać .ani .., ale GLOBIGNORE=.; echo ./.*(lub echo /bin/.*) będzie! Aby zignorować .i ..ze wszystkich globów, wygląda na to, że potrzebujesz shopt -s extglobi GLOBIGNORE='?(*/)@(.|..)'.
Stéphane Chazelas
1
Właściwie nie, GLOBIGNORE='?(*/)@(.|..)'to nie wyklucza ., a ..w .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)'rozbija globusy jak ./*...
Stéphane Chazelas
3

Z sekcji „Rozszerzenie nazwy ścieżki” w man bash:

Nazwy plików „.” I „..” są zawsze ignorowane, gdy jest ustawiony GLOBIGNORE, a nie null.

John1024
źródło