Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
add comment

3 Answers 3

up vote 7 down vote accepted

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

shopt -s dotglob
echo *
share|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
add comment

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.

share|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
add comment

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]*
share|improve this answer
add comment

Your Answer

 
discard

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.