How does GLOBIGNORE work?

9,956

Solution 1

Scroll down

The filenames . and .. are always ignored when GLOBIGNORE is set and not null.

Most of the time, it is not desirable to include . and .. as wildcard matches, since they don't represent files inside the directory — they're hacks to make directory navigation work. In fact, the origin of dot files is a bug in an early version of the ls command. The author meant to exclude . and .. from the listing but accidentally excluded all files that begin with .. Thus dot files became hidden from ls. Shells followed suit by hiding dot files like ls. However the way this was done was again a hack: files beginning with . are only excluded if the dot isn't matched explicitly in the pattern. So the pattern .* includes . and ...

To preserve compatibility with existing scripts, modern shells still include . and .. (except zsh, which on this issue like many others has a saner but not backward compatible behavior). However, if you set GLOBIGNORE, you are using a bash-specific feature, which shows that you aren't interested in backward compatibility. So pattern matching changes to exclude . and .. from all pattern matches.

Setting GLOBIGNORE=. excludes a file that is excluded automatically anyway whenever GLOBIGNORE is set, so it is equivalent to shopt -s dotglob except that . and .. are furthermore excluded from all patterns.

Solution 2

From the section entitled "Pathname Expansion" in man bash:

The file names ''.'' and ''..'' are always ignored when GLOBIGNORE is set and not null.

Share:
9,956

Related videos on Youtube

Ernest A
Author by

Ernest A

Updated on September 18, 2022

Comments

  • Ernest A
    Ernest A almost 2 years

    According to bash's manual page:

       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.
    

    However in practice...

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

    Why is .. removed from the list of matches? As far as I know, the pattern . does NOT match .., does it?

  • Stéphane Chazelas
    Stéphane Chazelas over 8 years
    Actually, no, GLOBIGNORE='?(*/)@(.|..)' would fail to exclude . and .. in .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)' would break globs like ./*...