Yesterday I did something stupid which I today realised. I ran:

/root# chmod o-rwx * .*

This supposed to remove read, write and execute permissions for the world on all files in the current directory (/root). As soon as I did this, screen behaved weird, I couldn't run commands as a non-root user, and ssh refused to work unless I logged in with root.

This was caused by the fact that bash expanded .* to .. too! Now, how do I chmod all files in a directory with chmod, without using find, a loop or another language like perl?


If you're using bash then setting dotglob will make * also match files that begin with a ..

shopt -s dotglob
echo *
| improve this answer | |
  • And for disabling it, shopt -u dotglob should be run. Thanks, if there is not other way, I'll accept this one I :) – Lekensteyn Dec 12 '10 at 9:13
  • The other way is .[^.]* ..?* *, but that leaves you open to problems if you don't use nullglob. – Ignacio Vazquez-Abrams Dec 12 '10 at 9:24

You say "without using find", but find really is the right tool for this job because it provides a high level of control. You can tell it to recurse or not, change directories or not, etc... For example:

  • All files in the current directory: find . -maxdepth 1 -type f
  • All entries (files+directories+others): find . -maxdepth 1

Find doesn't normally distinguish between regular files and "hidden" files, but it does not include ... If you want it to ignore them you can add '!' -name '.*', if you want it to operate only on dot files you can add -name '.*'.

Another nice thing about it is that you can do the above, and it prints out the entries it will operate on. So add "| less" to the end and you can eyeball what it will operate on before actually doing the changes. This review step may have prevented the problem you saw.

Once you have a find command you like, you can get it to run the chmod command by adding -exec chmod o-rwx '{}' ';' to the end. Change ';' to + if your find version supports it.

Really, find is a tool you shouldn't be afraid to use in this sort of situation, it really is the right tool for the job.

| improve this answer | |
  • The reason I want to avoid find is because it executes chmod for each file. Hence, it's a bit slower, but you're right, it is a very useful tool with many powerful possibilities. +1 for the detailed explanation. – Lekensteyn Dec 12 '10 at 21:25
  • 1
    The "+" will avoid executing a chmod for every file, but that's really only a consideration if you have more than a few thousand files. Since you're talking about a single directory and not recursive, if you have enough files in there that this matters, you probably have bigger problems... Also note that find+exec won't bomb out if your command-line gets too big, it will automatically run 2 or more chmods. If your find doesn't support "+", you can use "-print0" with find and then | xargs -0 chmod o-rwx to get the same results. – Sean Reifschneider Dec 12 '10 at 21:36

It's short and cheerful, and not completely reliable in the sense that it misses dotfiles with odd names (eg .+baz), but as there are very few of those, I taught myself to do

chmod -R foo:bar * .[0-z]*
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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