Bash: .* Considered Harmful To Match Dot Files. Why?

by on April 24, 2013 · 5 comments· LAST UPDATED April 25, 2013

in , , ,

How do I match dot files under Unix / Linux using bash shell? Why .* considered as harmful when matching dot files under bash shell?

Short answer - .* matches the special ".." link in the directory and your command ends up getting applied to the parent directory. This may end up in unexpected results. Hence, .* considered harmful.

Long answer - Say, you want to run a chmomd/chown or find command on all of the dot files in a directory called /home/nixcraft/projects. You type the following command in $HOME/projects/ to match all dot files:

Tutorial details
DifficultyEasy (rss)
Root privilegesNo
RequirementsBash
Estimated completion timeN/A
chmod -R 0444 .*

OR

chown -R user:group .*

This will change the permission for both in the current and parent directory as .. will be matched by .*. This may result into unexpected security related issues and few other problems. Many Linux / Unix commands offers an option to work recursively on files. In this example, the -R option will match the current and all sub-dirs of parent directory. This can result into disaster if you have several thousand files. Restoring and cleaning from this kind of problems can be time consuming. Use the following syntax to match dot files:

 
chmod -R 0444 .[^.]*
 

OR

 
chown -R user:group .[^.]*
 

OR

 
ls -R .[^.]*
 

OR

 
find . -iname ".[^.]*" -print
 

OR

 
find . -iname ".[^.]*" -ls
 
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 5 comments… read them below or add one }

1 Philippe Petrinko April 25, 2013 at 9:14 am

Hi,
Good to say.

By the way:

1) [find] could be set to find files only with [-type] parameter set to [f].

find . -type f -iname “.[^.]*” -print

2) In this case, there is no need to use special search string, and you can use “.*”

3) Finally, there is also no point in using case-insensitive search [-iname], normal search [-name] will make it.

So, this is appropriate to use:

find . -type f -name “.*” -print

You may consider modifying your article accordingly.

– Philippe

Reply

2 jec April 25, 2013 at 7:23 pm

Simpler while not so complete as above solutions:

chmod -R +x .??*

This will match anything beginning by dot but not a filename with only ONE char after dot (.a for example)

Reply

3 Philippe Petrinko April 25, 2013 at 8:32 pm

Not totally bad, but as you said, this does not do the trick for all cases… ;-)
so I won’t use your code and stick to :

find . -type f -name “.*” -print | xargs # do here whatever you need

Reply

4 gdott9 April 28, 2013 at 1:07 pm

Well, it depends on your shell.

When I try ‘ls -d .*’, zsh does not return . and .. whereas bash returns both.
So, with zsh, it’s not harmful, but, yes, be careful with that.

Reply

5 leviathaan January 10, 2014 at 4:13 pm

why .* and not * ?

Reply

Leave a Comment

Tagged as: , , , ,

Previous Faq:

Next Faq: