Basic Approach
To recursively change permissions for all files (but not directories) contained in the current directory and all of its subdirectories:
Linux:
chmod 644 `find -type f`
macOS, BSD, and Windows (Git Bash/WSL):
chmod 644 `find . -type f`
Explanation:
find -type f
(Linux) orfind . -type f
(macOS/BSD) - finds all files in the current directory and subdirectories- The backticks
`
capture the output of the find command and pass it as arguments to chmod chmod 644
- sets file permissions to read/write for owner, read-only for group and others
Targeting a Specific Directory
If you want to target a different directory, substitute .
with the correct path:
chmod 644 `find /home/user/special/folder -type f`
Explanation:
/home/user/special/folder
- replace this with the path to your target directory
Compatibility: this works on most Linux distributions, as well as macOS, BSD, and Windows (Git Bash/WSL).
Using find -exec
for Improved Compatibility
A more reliable approach that works across all platforms is to use find
with the -exec
flag:
find . -type f -exec chmod 644 {} \;
Explanation:
find .
- starts the search in the current directory-type f
- limits the search to files only-exec chmod 644 {} \;
- for each file found, execute the chmod command. The{}
is replaced with the filename, and\;
terminates the command
NOTE: This creates a separate subprocess for every single file, which can be slow for large numbers of files.
Using xargs
for Better Performance
To improve performance when dealing with many files, use xargs
to batch file names into groups:
find . -type f -print0 | xargs -0 chmod 644
Explanation:
find . -type f
- finds all files in the current directory and subdirectories-print0
- terminates each filename with a NUL character (instead of a space or newline), which safely handles filenames with spaces, newlines, or special characters| xargs -0
- pipes the output to xargs, which reads NUL-terminated input and batches filenames into groupschmod 644
- changes permissions for all files in each batch- This method is more efficient than
-exec
because it reduces the number of subprocesses created.
Compatibility: this works on Linux, macOS, BSD, and Windows (Git Bash/WSL with proper xargs
support).
Using find -exec
with +
for Most Efficiency
If you have GNU find
(common on Linux and available on macOS/BSD), use the most efficient approach:
find . -type f -exec chmod 644 {} +
Explanation:
find . -type f
- finds all files in the current directory and subdirectories-exec chmod 644 {} +
- instead of running chmod once per file, this batches multiple files together and runs chmod once for the entire batch (similar to xargs)- The
+
at the end (instead of\;
) tells find to pass as many filenames as possible to a single chmod command - This is the most efficient method and handles special characters in filenames correctly
Compatibility: this works on Linux (GNU find
), macOS (10.6+), modern BSD systems, and Windows (Git Bash/WSL with GNU find
).
Changing Permissions for Directories Only
If you need to change permissions for directories (but not files), use -type d
instead:
# Make directories executable/searchable
find . -type d -exec chmod 755 {} +
Explanation:
-type d
- limits the search to directories onlychmod 755
- sets directory permissions to read/write/execute for owner, read/execute for group and others
Platform-Specific Notes
Linux
All methods work on Linux, the most efficient is:
find . -type f -exec chmod 644 {} +
macOS
Modern macOS (10.6+) supports GNU find
features:
find . -type f -exec chmod 644 {} +
For older macOS versions, use the xargs
method:
find . -type f -print0 | xargs -0 chmod 644
BSD
Modern BSD systems support the +
syntax:
find . -type f -exec chmod 644 {} +
For older BSD versions, use the xargs
method:
find . -type f -print0 | xargs -0 chmod 644
Windows (Git Bash/WSL)
Git Bash and WSL (Windows Subsystem for Linux) include GNU tools:
find . -type f -exec chmod 644 {} +
NOTE: Native Windows (without Git Bash or WSL) doesn't support Unix-style
chmod
. Use Windows file properties oricacls
instead.
Common Permission Settings
Here are some common permission values you might want to use:
# Read/write for owner, read-only for group and others (files)
find . -type f -exec chmod 644 {} +
# Read/write/execute for owner, read/execute for group and others (shell scripts)
find . -type f -name "*.sh" -exec chmod 755 {} +
# Read/write for owner only (private files)
find . -type f -exec chmod 600 {} +
# Read/write/execute for owner only (private scripts)
find . -type f -name "*.sh" -exec chmod 700 {} +
Performance Comparison
Here's how the different methods compare when dealing with large numbers of files:
Method | Performance | Safety | Compatibility |
---|---|---|---|
Backticks `find` | Fast for small sets | ✗️ Breaks on special chars | All platforms |
-exec chmod {} \; | Slow (one process per file) | ✓ Safe | All platforms |
| xargs -0 | Fast (batched) | ✓ Safe | All platforms |
-exec chmod {} + | Fastest (batched) | ✓ Safe | Modern systems |
RECOMMENDATION: Use
find . -type f -exec chmod 644 {} +
for the best combination of performance and safety on modern systems.