Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This has been discussed before here.

What I'd like to know is how to turn these:

Recursive chmod only files within this folder:

find . -type f -exec chmod 0600 {} \;

Recursive chmod only folders within this folder:

find . -type d -exec chmod 0755 {} \;

into a bash script, so it could be something like:

For files:

rchmodf 744 .

For directories:

rchmodd 755 .

and... also maybe into a nautilus right click menu option if that's possible.

share|improve this question
up vote 9 down vote accepted

Here's a script you can call by passing the mode as the first argument and one or more directory names as subsequent arguments. Under Linux, if you don't pass any directory name, it'll be as though you passed . (the current directory). Name this script rchmodf, make it executable (chmod a+rx /path/to/rchmodf) and put it somewhere on your $PATH.

mode=$1; shift
find "$@" -type f -exec chmod "$mode" {} +

Explanations: mode=$1; shift sets the variable mode to the first argument of the script and removes that first argument from the list. "$@" expands to the list of all arguments.

If you like, you can make a script that accepts both a directory mode and a file mode.

dir_mode=$1; shift
file_mode=$1; shift
find "$@" -type d -exec chmod "$dir_mode" {} + -o -type f -exec chmod "$file_mode" {} +

Note that 744 isn't a useful file mode; 644 (user-writable and world-readable) and 755 (also world-executable) are much more common. Also, changing every file in a tree to be executable or not to be executable is rarely useful; you'll probably want to call this script with arguments like +rX (capital X, to set the executable bit only for directories and for files that are already executable). In fact, the X symbolic mode is probably what you were after with these scripts: chmod -R +rX ..

With bash or zsh, there's another way to act recursively but on directories only. For bash, you need version 4 and to run shopt -s globstar first.

chmod a+rx **/*/

In zsh, you can act on files only by suffixing (.): chmod a+r **/*(.).

I'll pass on the Nautilus question.

share|improve this answer
Ninjas an nincompoops! You can use one find to execute different commands on different result sets? +1 for overloading the OR operator. – Caleb Jun 11 '11 at 7:52

Script linked to by user23538, hope you don't mind.

I have tried it and it works well. Please note that if you use . as the path argument (run it in the same directory where the script is located), it does in fact change the scripts own file permissions to 644, so put it in the directory above.

# chmodr.sh
# author: Francis Byrne
# date: 2011/02/12
# Generic Script for recursively setting permissions for directories and files
# to defined or default permissions using chmod.
# Takes a path to recurse through and options for specifying directory and/or
# file permissions.
# Outputs a list of affected directories and files.
# If no options are specified, it recursively resets all directory and file
# permissions to the default for most OSs (dirs: 755, files: 644).

# Usage message
echo "Usage: $0 PATH -d DIRPERMS -f FILEPERMS"
echo "Arguments:"
echo "PATH: path to the root directory you wish to modify permissions for"
echo "Options:"
echo " -d DIRPERMS, directory permissions"
echo " -f FILEPERMS, file permissions"
exit 1

# Check if user entered arguments
if [ $# -lt 1 ] ; then

# Get options
while getopts d:f: opt
case "$opt" in
\?) usage;;

# Shift option index so that $1 now refers to the first argument
shift $(($OPTIND - 1))

# Default directory and file permissions, if not set on command line
if [ -z "$DIRPERMS" ] && [ -z "$FILEPERMS" ] ; then

# Set the root path to be the argument entered by the user

# Check if the root path is a valid directory
if [ ! -d $ROOT ] ; then
echo "$ROOT does not exist or isn't a directory!" ; exit 1

# Recursively set directory/file permissions based on the permission variables
if [ -n "$DIRPERMS" ] ; then
find $ROOT -type d -print0 | xargs -0 chmod -v $DIRPERMS

if [ -n "$FILEPERMS" ] ; then
find $ROOT -type f -print0 | xargs -0 chmod -v $FILEPERMS
share|improve this answer
@user23538 was already instructed to paste the code in a block on-site. You should not then post exactly that unless you have something more to add. – HalosGhost Jun 25 '14 at 18:16
They were instructed to, but they didn't. So I did. That is what was requested, even if I'm not the same person. Please explain why this is incorrect? – Kluny Jun 25 '14 at 18:49
Ahh, I missed how long ago the user had posted their answer. If you find something about your answer to edit, I will be happy to remove my down-vote. – HalosGhost Jun 25 '14 at 18:51
Thank you, I added a note that I've tested the script. – Kluny Jun 25 '14 at 18:54

I wrote a script that basically does the above but also provides a bit of flexibility for command line options (directory and/or file permissions, or exclude both it automatically resets everything to 755-644). It also checks for a few error scenarios.


Hope it helps!

share|improve this answer
You should paste the code here. That way, we avoid lots of dead links in the future. If you're worried about the two versions drifting apart, you can still leave the link there for reference. – l0b0 Sep 22 '12 at 8:50

Your Answer


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.