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
| Command | Directory (was 700) | Data file (was 600) | Script (was 700) |
|---|---|---|---|
chmod -R 755 | 755 rwxr-xr-x | 755 rwxr-xr-x | 755 rwxr-xr-x |
chmod -R 644 | 644 rw-r--r-- | 644 rw-r--r-- | 644 rw-r--r-- |
chmod -R u=rwX,go=rX | 755 rwxr-xr-x | 644 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+rX | 755 rwxr-xr-x | 644 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/siteOptions 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.