Can anyone point me to either code or a tutorial for writing a shell script that can recursively go through an entire directory structure (starting at the current working directory, or given an required argument of where to start at) and can:

  1. Determine whether an item is a directory, and if it is, chmod 755 it, or...
  2. Determine whether an item is a file (not a dir), and chmod 644 it.

I'm looking for compatibility with Ubuntu, Debian, RHEL-Based, etc., so I'm not tagging this with any particular language. I'd like this in Bash, but if you have a ZSH script, that will work also.


I am used to this one-line command (will recurse starting in current working directory)

find . -type d -exec chmod 0755 '{}' + -or -type f -exec chmod 0644 '{}' +


find .                    # starting in curdir find   
-type d                   # any directory
-exec chmod 0755 '{}'     # and chmod it to 755
+                         # (variant of -exec look find man page)
-or                       # or
-type f                   # any file
-exec chmod 0644 '{}'     # and chmod it to 644
+                         # (as above)
  • That worked. I take it if I do this in a script, and I set a cd /path/to/dir/ it will change the working directory, so I can use it as an argument-based command/script? – Thomas Ward Jun 17 '12 at 0:12
  • I just tested and cd does appear to change the working directory in a script. Not sure if there are any exceptions to that, though. – user19866 Jun 17 '12 at 1:15
  • @palintropos cd does change the working directory in scripts. If that has ever not happened for you, that's quite strange. You might want to post a new question about that ...with details. – Eliah Kagan Jun 17 '12 at 2:28
  • @palitropos in your script you can just pass the topmost directory to find instead of . – guido Jun 17 '12 at 3:16
  • 1
    Tiny nitpick: this would be a fully portable solution with -o instead of -or (a GNUism, same applies to -and). – ormaaj Jun 17 '12 at 8:30

The simple answer:

chmod -R a+rX .

+X (note the capital X) means to give the execute permission if the execute permission was already present for some user. If you have a directory tree which has the right permissions for the owner and you want to make it accessible to everyone, this is the right command to use. It not only makes directories world-executable, but also executable files.

If you also want to reset write permissions to owner only and clear any setuid/setgid bit, make that

chmod -R a-ws,u+w,a+rX .

The obligatory zsh two-liner, if you don't want to make any file executable:

chmod 755 **/*(/)
chmod 644 **/*(.)

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.