chmod all files (including hidden files) in a directory in Linux (not recursively)

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?


Solution 1:

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

shopt -s dotglob
echo *

Solution 2:

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.