The character .
is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*
, the *
matches strings beginning with .
, so .*
includes ..
(as well as .
, with *
matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.
It would make sense to make an exception and to systematically exclude .
and ..
from matches, but that's not how it was done historically, so many Bourne/POSIX shells (sh
, dash
, bash
, AT&T ksh
, yash
…) include them, as do (t)csh and even fish 1.x. A few shells exclude .
and ..
from all wildcard matches: zsh, pdksh/posh/mksh (unlike AT&T ksh), fish ≥2.0.
If you set GLOBIGNORE
to any non-empty value, bash switches to the convenient but non-standard behavior of excluding .
and ..
from matches. Setting GLOBIGNORE
also turns off the behavior of excluding dot files; with GLOBIGNORE='.*'
, you get the usual behavior of ./*
excluding dot files, but ./.*
matches only dot files and not .
or ..
. Set GLOBIGNORE=.:..
(or GLOBIGNORE=.
) to have ./*
match all files, including dot files, but excluding .
and ..
.
In ksh93, set FIGNORE='@(.|..)'
to exclude .
and ..
from matches but include dot files. Thus .*
will expand to dot files but not include .
or ..
.
Without resorting to shell-specific features, you can match dot files with the following two globs:
.[!.]* ..?*
and all files (excluding .
and ..
) with the following three globs:
..?* .[!.]* *
But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.
To avoid surprises, it might be easier to use find
. find
never recurses to the parent directory (unless told to follow symbolic links).
find /home/username/. -name . -o -prune -name '.*' -exec chown -R username:groupname {} +
./.*
will include./.
and./..
, which is why you get that evil recursivity covering your entire system in the first place../.*
would have been ending up in the same disaster, if I got you right?ls -d ./.*
. It includes..
, the parent directory. And this directory would include its parent as well, and so on... Runls --recursive ./.*
and you'll see it...rm
specifically protects against this; commands likechmod
andchown
do not.