Как работает GLOBIGNORE?

15

Согласно странице руководства 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.

Однако на практике ...

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

Почему ..убирается из списка матчей? Насколько я знаю, шаблон .не совпадает .., не так ли?

Эрнест А
источник

Ответы:

14

Прокрутите вниз ...

Имена файлов .и ..всегда игнорируются, когда GLOBIGNOREустановлено, а не ноль.

Большая часть времени, это не желательно включать .и в ..качестве подстановочных матчей, так как они не представляют собой файлы в директории - они писаки , чтобы сделать каталог навигацию работы. Фактически, происхождение точечных файлов является ошибкой в ​​ранней версии lsкоманды . Автор хотел исключить .и ..из списка, но случайно исключил все файлы, которые начинаются с .. Таким образом, точечные файлы стали скрытыми от ls. Снаряды следовали примеру, скрывая точечные файлы вроде ls. Однако способ, которым это было сделано, снова был хаком: файлы, начинающиеся с ., исключаются, только если точка не соответствует явно в шаблоне. Таким образом, шаблон .*включает в себя .и ...

Чтобы сохранить совместимость с существующими сценариями, современные оболочки по-прежнему включают .и ..(кроме zsh, который в этом вопросе, как и многие другие, имеет более разумное, но не обратно совместимое поведение). Однако, если вы установите GLOBIGNORE, вы используете специфичную для bash функцию, которая показывает, что вы не заинтересованы в обратной совместимости. Таким образом, сопоставление с образцом изменяется для исключения .и ..из всех совпадений с образцом.

Параметр GLOBIGNORE=.исключает файл, который в любом случае автоматически исключается всякий раз, когда GLOBIGNOREон задан, поэтому он эквивалентен shopt -s dotglobисключению .и .., кроме того, исключается из всех шаблонов.

Жиль "ТАК - перестань быть злым"
источник
1
На самом деле, я только что понял установку GLOBIGNOREтолько игнорирования .и ..в шаблонах без слешей, а GLOBIGNORE фильтрует пути к файлам, а не имена файлов. GLOBIGNORE=.; echo .*не будет включать .ни .., но GLOBIGNORE=.; echo ./.*(или echo /bin/.*) будет! Чтобы игнорировать .и ..от всех шаров, похоже, что вам нужно shopt -s extglobи GLOBIGNORE='?(*/)@(.|..)'.
Стефан Шазелас
1
На самом деле, нет, GLOBIGNORE='?(*/)@(.|..)'не исключат .и ..в .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)'сломал бы шары как ./*...
Стефан Шазелас
3

Из раздела «Расширение пути» в man bash:

Имена файлов ''. '' И '' .. '' всегда игнорируются, когда установлен GLOBIGNORE, а не равен NULL.

John1024
источник