Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

According to bash's manual page:

          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 .*

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

share|improve this question
up vote 12 down vote accepted

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.

share|improve this answer
Actually, I just realised setting GLOBIGNORE only ignore . and .. in slash-less patterns and GLOBIGNORE filters file paths not file names. GLOBIGNORE=.; echo .* will not include . nor .., but GLOBIGNORE=.; echo ./.* (or echo /bin/.*) will! To ignore . and .. from all globs, it looks like you need shopt -s extglob and GLOBIGNORE='?(*/)@(.|..)'. – Stéphane Chazelas Mar 6 at 21:46
Actually, no, GLOBIGNORE='?(*/)@(.|..)' would fail to exclude . and .. in .*/foo. GLOBIGNORE='?(*/)@(.|..)?(/*)' would break globs like ./*... – Stéphane Chazelas Mar 6 at 22:29

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

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.