Skip to content

chmod -R

chmod -R mode dir applies the same mode to the directory and to every file and subdirectory below it, so a numeric mode like 755 also marks every file executable; set directories and files separately with find, or use a symbolic mode with capital X.

What each recursive command does

Result on a directory, a data file and a script
CommandDirectory (was 700)Data file (was 600)Script (was 700)
chmod -R 755755 rwxr-xr-x755 rwxr-xr-x755 rwxr-xr-x
chmod -R 644644 rw-r--r--644 rw-r--r--644 rw-r--r--
chmod -R u=rwX,go=rX755 rwxr-xr-x644 rw-r--r--755 rwxr-xr-x
chmod -R u=rwX,g=rX,o=750 rwxr-x---640 rw-r-----750 rwxr-x---
chmod -R a+rX755 rwxr-xr-x644 rw-r--r--755 rwxr-xr-x

Why chmod -R with a number is usually wrong

Directories and files want different modes: a directory needs execute to be entered, a data file should not have it. A single number cannot express both. chmod -R 755 makes every file executable, and chmod -R 644 removes execute from every directory, after which nobody but root can enter them.

The two correct patterns

find selects directories and files separately. The + at the end of -exec passes many paths per chmod call, which is far faster than \; on large trees.

A capital X adds execute only to directories and to files that already have execute for someone, so one symbolic command can set both kinds correctly and keep existing scripts runnable.

find /var/www/site -type d -exec chmod 755 {} +
find /var/www/site -type f -exec chmod 644 {} +

# or in one pass, keeping existing scripts executable:
chmod -R u=rwX,go=rX /var/www/site

Options worth knowing

GNU chmod does not follow symbolic links it meets while recursing; -H follows links given on the command line and -L follows every link to a directory. -c prints only the files it actually changed, which makes a dry run of the damage easy to review.

GNU chmod does not protect / by default: chmod -R 777 / will run. Add --preserve-root in scripts, or double-check variables so an empty $DIR does not turn into /.

chmod -R -c go-w ./site     # show what changed
chmod -R --preserve-root u=rwX,go=rX "$DIR"

Frequently asked questions

How do I chmod 755 only directories?
find . -type d -exec chmod 755 {} + changes directories only. Use -type f with 644 for files.
What does capital X mean in chmod?
Execute, but only for directories and for files that already have an execute bit for someone. It lets one recursive command handle both directories and files.
Does chmod -R follow symbolic links?
GNU chmod skips symbolic links it meets while recursing, and changes a link's target only when the link is named on the command line. Add -L to follow every link to a directory, or -H for command-line links only.
Is chmod -R the same on macOS?
Yes for -R and the modes. macOS chmod is the BSD version: it has no --preserve-root or -c, and stat uses -f instead of -c.

Last reviewed by Arielton Oberek.