Contact Us

Got questions, inquiries, or opportunities for collaboration? We are just a message away!

Use chmod For Files But Not Directories

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) or find . -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 groups
  • chmod 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 only
  • chmod 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 or icacls 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:

MethodPerformanceSafetyCompatibility
Backticks `find`Fast for small sets✗️ Breaks on special charsAll platforms
-exec chmod {} \;Slow (one process per file)✓ SafeAll platforms
| xargs -0Fast (batched)✓ SafeAll platforms
-exec chmod {} +Fastest (batched)✓ SafeModern systems

RECOMMENDATION: Use find . -type f -exec chmod 644 {} + for the best combination of performance and safety on modern systems.