Table of Contents
Let me guess if you are here, not able to assign permission to directories and files? Getting permission denied error? Or you have a lot of directories and files and trying to figure how how to use chmod recursively to change permissions? Do you want to apply 777 or 755 permission across all the files or directories?
Well you are at the right place. In this tutorial guide I will help us understand the usage of chmod
and how you can change permissions of files and directories using a single command
What is chmod?
chmod
is a GNU utility which is provided as part ofcoreutils
rpm in Linux distributionschmod
is short abbreviation for "Change Mode"- It is used to change the file mode bits of each given file/directory according to mode.
- You can either use symbolic representation of changes or an octal number representing the bit pattern for the new mode bits.
- The format of a symbolic mode is
[ugoa...][[-+=][perms...]...]
where perms is either zero or more letters from the set rwxXst - You can also add/modify/remove special permissions such as
setuid
,setgid
,sticky bit
withchmod
What is --preserve-root? Why you should use it?
- In this tutorial I will be using
--preserve-root
with all of mychmod
commands - This is a recommended option to use when you are planning to assign permission recursively as this can be destructive
- Imagine by mistake you removed all permission from
/ (root)
directory, this would lead in an unusable system - It is similar to running
rm -rf /
which if you are a Linux Administrator should know, this can destroy your server - With
--preserve-root
we inform the command not to modify root directory permission
DO NOT USE THIS COMMAND
# chmod --changes --recursive 755 /
Snippet from my terminal with this command, see the damage this command can do to your server.

This would recursively change the permission of all files and dir under /
which can also destroy your system
In such case it is always recommended to use
# chmod --changes --recursive --preserve-root 755 /
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe
It may not be possible to use this additional option every time with chmod
so you can create an alias
# alias chmod='chmod --preserve-root'
and also add this to your /etc/bashrc
or individual user's .bashrc
file for permanent changes
Now if we use chmod
, it does not allow to modify root permission
# chmod -c --recursive 755 /
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe
Linux Permissions Syntax
You can use this table to understand the different symbolic or octal value to use with chmod
Permission | Octal | Syntax (Symbolic) |
---|---|---|
read+write+execute | 4+2+1=7 | rwx |
read+write | 4+2+0=6 | rw- |
read+execute | 4+0+1=5 | r-x |
read | 4+0+0=4 | r-- |
write+execute | 0+2+1=3 | -wx |
write | 0+2+0=2 | -w- |
execute | 0+0+1=1 | --x |
Perform chmod recursive with -R or --recursive
If all your files and directories are under one parent directory then you can directly use chmod -R <dir_name>
to assign the permission recursively
The syntax to modify the file and directory permission recursively:
chmod [--changes|-c] {--recursive|-R} {PATH}
I hope you know, in a syntax anything under square braces []
is optional and anything under curly braces {}
is mandatory
In this syntax I have also added --changes
or -c
as optional as this will inform you if the change really happened in the backend
To assign 755 permission of all files and directories under /opt/dir
# chmod -c -R 755 /opt/dir
This would also remove any special permission if already assigned to any of the files or directories under /opt/dir
. For example, I created a file with Sticky Bit Special permission under /opt/dir
. Once I apply chmod
recursively, the special sticky bit permission was also removed
mode of '/opt/dir/' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---) mode of '/opt/dir/file' changed from 7555 (r-sr-sr-t) to 0750 (rwxr-x---)
/opt/dir
and not the permission of /opt/dir
itself then you should use chmod -c -R <permission> /opt/dir/*
. This will change permission of everything under /opt/dir/
but not for dir
directory itselfYou can also use octal method here, in this example I have added full permission to user, read and execute permission for for group and removed all permission from others which is equivalent to 750 in octal method
# chmod -c -R u+rwx,g+rx,o-rwx /tmp/dir1/*
mode of '/tmp/dir1/dir2/file5' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3/file1' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3/file2' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3/file5' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3/file3' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
mode of '/tmp/dir1/dir2/dir3/file4' changed from 0755 (rwxr-xr-x) to 0750 (rwxr-x---)
Verify the permission
# tree -p /tmp/dir1/
/tmp/dir1/
├── [drwxr-x---] dir2
│ ├── [drwxr-x---] dir3
│ │ ├── [-rwxr-x---] file1
│ │ ├── [-rwxr-x---] file2
│ │ ├── [-rwxr-x---] file3
│ │ ├── [-rwxr-x---] file4
│ │ └── [-rwxr-x---] file5
│ └── [-rwxr-x---] file5
└── [-rwxr-x---] file10
2 directories, 7 files
Since I used /tmp/dir1/*
in my command, the permission of dir1
is not modified.
# ls -ld /tmp/dir1/
drwxr-xr-x 3 root root 4096 May 23 12:02 /tmp/dir1/
chmod
recursively as it is ir-reversibleNow some of the drawbacks of above command
- It will modify the permission of all the files and directories under single path. If you have many files or directory under different locations such as
/opt
,/var
,/tmp
then you will end up executingchmod
multiple times - There is no way to differentiate between files and directories. If you have a requirement to change permission of only files or directories then the tool itself can not handle this
- Similarly if you want to change permission of certain files or directory with specific naming syntax, the tool can not handle itself such filter
So we need find
command to take care of these filters before applying chmod
command
find
can apply these filters and then it can be combined with exec or xargs
to execute chmod
command. If you use find
in combination with chmod
then you do not need --recursive
or -R
as find
itself will search all the files and pass individual file for chmod
as an input argument. Let me give you some examples to help you understand better:
Use find with exec to change permission
I have already written a descriptive tutorial to learn and understand find and exec combination.
The syntax to change permission using find
with chmod
would be
find {PATH} [OPTIONS] -exec [COMMAND] {} \;
- Replace
PATH
with the location of your files or directories - You can choose all the supported options with find command such as define
-type
, or-name
etc - Replace
COMMAND
withchmod <permission>
- Do not remove or replace
{} \;
as this will be used by find to recursively look for files or directories and provide the found file as an input argument toCOMMAND
- So if find command finds a file named
myfile
then theCOMMAND
would become "chmod <permission> myfile
"
Search for all files under /tmp
and change their permission to 644
# find /tmp -type f -exec chmod --changes 644 {} \;
To assign the same permission using symbolic method:
# find /tmp -type f -exec chmod --changes u=rw,go=r {} \;
Search for all directories under /tmp
and change their permission to 755
# find /tmp -type d -exec chmod --changes 755 {} \;
To assign the same permission using symbolic method:
# find /tmp -type d -exec chmod --changes u=rwx,go=rx {} \;
Use find with xargs to change permission
Similarly you can also combine find with xargs
to assign permission recursively
The syntax to use find with xargs and chmod would be:
find {PATH} [OPTIONS] -print0 | xargs -0 [COMMAND]
Here,
-print0
Tells find to print all results to std, each separated with the ASCII NUL character ‘\000’
-0
Tells xargs that the input will be separated with the ASCII NUL character ‘\000’
Search for all files under /tmp
and change their permission to 644
# find /tmp -type f -print0 | xargs -0 chmod --changes 644
To assign the same permission using symbolic method:
# find /tmp -type f -print0 | xargs -0 chmod --changes u=rw,go=r
Search for all directories under /tmp
and change their permission to 755
find /tmp -type d -print0 | xargs -0 chmod --changes 755
To assign the same permission using symbolic method:
# find /tmp -type d -print0 | xargs -0 chmod --changes u=rw,go=rx
Conclusion
chmod
can be used with -R
or also referred as --resursive
to assign/modify permission to files and directories recursively. Although it is recommended to use --changes
and --preserve-root
along with the command to avoid any destruction.
It is possible that you may not want out STDOUT
on the screen so you can choose to reduce all messages and errors to a different file by using
# chmod --recursive --changes 755 /tmp/dir1/ >& /tmp/logfile
So this would store all the output to /tmp/logfile
which you can use for debug purpose.
Lastly I hope the steps from the article to apply chmod
recursively on Linux was helpful. So, let me know your suggestions and feedback using the comment section.
References
I have used below external references for this tutorial guide
man page for chmod