How to run chmod recursively
As a quick reference, here’s why chmod recursion is tricky:
# NOT what you want, because files and directories require separate treatment
chmod -R 644 *
# The correct way:
# Set _files_ in the current directory and its subdirectories to 644
find . -type f -exec chmod 644 "{}" \;
# Set _directories_ in the current directory to 755
find . -type d -exec chmod 755 "{}" \;The short (and wrong) answer to "how do I run chmod recursively" is "with the -R switch." For example chmod -R 644 \ will indeed change everything to -rw-r--r-- permissions, but that's almost \never\ what you actually want to do. Even at the most basic level, directories and files need different permissions (755 and 644, respectively), and setting both to the same permissions will result in problems.
Using find with -exec
The correct answer to recursive chmod is to use find with the -exec flag. This will let you target files and directories by type, name, extension, etc., and apply permissions selectively to matching files and directories.
With find you can filter out the specific files/types you want to affect, and then use the -exec flag to perform a command on the matched files, in this case chmod. The find command is recursive by default, including all subdirectories (and their subdirectories). You can limit how deep the command traverses with the -depth n flag.
To affect only the \files\ in the current directory and its subdirectories, we'll use find -type f ("find type file") and apply standard file permissions of 644 to the files:
$ find . -type f -exec chmod 644 "{}" \;The {} is replaced with each matching file, applying the exec command one at a time, and the quotes allow for spaces and other reserved characters in the filename. -exec commands must end with \;.
To do the same thing with directories, but apply 755 permissions:
$ find . -type d -exec chmod 755 "{}" \;With find, you can also target files by name, creation date, owner, and a host of other options, allowing you to target operations like chmod very precisely.
When you have a lot of files...
To speed up the process when working on a large number of files or directories, you can use -print0 to send a null-separated list, piping it to xargs -0 to execute a command on each entry.
$ find . -type d -print0 | xargs -0 chmod 755
$ find . -type f -print0 | xargs -0 chmod 644Note that with the find commands listed above, we're using . (current directory) as our base for finding files. You can insert any path in place of the . to execute the find from that base, e.g. /var/www or whatever you need.
So, to summarize, don't use chmod -R in almost any circumstance. Rather, use find ... -exec chmod ... to apply permissions selectively to files and directories based on their type or other parameters.
Related articles
Bash Comments
Comments will help make your scripts more readable
Reading User Input
Via command line arguments and prompting users for input
Curl Post Request
Use cURL to send data to a server
Bash If Statement
Learn how to use the if statement in Bash to compare multiple values and expressions.
Bash While Loop
Learn how to use and control the while loop in Bash to repeat instructions, and read from the standard input, files, arrays, and more.
Upload Files With curl
Learn how to upload a file to FTP, SFTP servers, Artifactory, and AWS S3 using the curl command.
How To Copy A Directory In Linux
Learn how to copy directories and their content in Linux using the cp command with options like -r for recursive copying, -i for interactive mode, and -a for preserving attributes.
Create Groups In Linux
Learn how to manually and automatically create and list groups in Linux.
How to Check the Size of Folders in Linux
Learn how to output the size of directories and subdirectories in a human-readable format in Linux and macOS using the du command.
Count Files in Linux
Learn how to count files and folders contained in directories and subdirectories in Linux using the ls, find, and wc commands.
List Open Ports in Linux
Learn how to output the list of open TCP and UDP ports in Linux, as well as their IP addresses and ports using the netstat command.
Format Command Output In Linux
Learn how to filter and format the content of files and the output of commands in Linux using the awk command.