ZetCode

Linux chmod Command

last modified October 23, 2026

The chmod (change mode) command in Linux changes the access permissions of files and directories. Permissions decide who can read, write, and execute a file: its owner, members of its group, and all other users.

Permissions can be given in numeric (octal) mode, such as 755, or in symbolic mode, such as u+x. Only the owner of a file or root can change its permissions. The concepts behind the permission bits are explained in the Linux file permissions article; here we focus on the command. The examples use GNU chmod from coreutils.

Numeric mode

In numeric mode, each of the three digits sets the permissions of the owner, the group, and others. Read is 4, write is 2, and execute is 1.

chmod 755 deploy.sh

A new script cannot be run because it lacks the execute permission. The mode 755 gives the owner rwx (4+2+1) and the group and others r-x (4+1). Numeric mode replaces all existing permissions.

$ ls -l deploy.sh
-rw-r--r-- 1 jano jano 32 Oct 23 09:00 deploy.sh
$ ./deploy.sh
bash: ./deploy.sh: Permission denied
$ chmod 755 deploy.sh
$ ls -l deploy.sh
-rwxr-xr-x 1 jano jano 32 Oct 23 09:00 deploy.sh
$ ./deploy.sh
deploying...

Common modes

A few numeric modes cover most needs.

chmod 600 id_key
chmod 644 notes.txt

600 keeps a file private to its owner, which SSH requires for private keys. 644 is the usual mode for regular files: the owner can edit them and everyone can read them. Directories typically use 755 or 700. The stat command shows the mode in both octal and symbolic form.

$ chmod 600 id_key
$ chmod 644 notes.txt
$ stat -c '%a %A %n' id_key notes.txt
600 -rw------- id_key
644 -rw-r--r-- notes.txt

Symbolic mode

Symbolic mode combines who (u, g, o, a), an operator (+, -, =), and permissions (r, w, x).

chmod u+x,g-r,o-r notes.txt
chmod a=r notes.txt
chmod ug+w notes.txt

The first command adds execute for the owner and removes read for the group and others; clauses are separated by commas. The = operator sets permissions exactly, so a=r makes the file read-only for everyone. Unlike numeric mode, + and - leave the other bits untouched.

$ chmod u+x,g-r,o-r notes.txt
$ ls -l notes.txt
-rwx------ 1 jano jano 6 Oct 23 09:00 notes.txt
$ chmod a=r notes.txt
$ ls -l notes.txt
-r--r--r-- 1 jano jano 6 Oct 23 09:00 notes.txt
$ chmod ug+w notes.txt
$ ls -l notes.txt
-rw-rw-r-- 1 jano jano 6 Oct 23 09:00 notes.txt

Reporting changes

The -v option reports every file processed, while -c reports only actual changes.

chmod -v 640 report.txt
chmod -c 640 report.txt
chmod -c o+r report.txt

The second command prints nothing, because the file already has mode 640. The reports show the old and new modes in both notations, which is useful with recursive changes.

$ chmod -v 640 report.txt
mode of 'report.txt' changed from 0644 (rw-r--r--) to 0640 (rw-r-----)
$ chmod -c 640 report.txt
$ chmod -c o+r report.txt
mode of 'report.txt' changed from 0640 (rw-r-----) to 0644 (rw-r--r--)

Copying permissions

The --reference option copies the mode of another file.

chmod --reference=id_key template.txt

The file template.txt now has the same 600 mode as id_key.

$ chmod --reference=id_key template.txt
$ stat -c '%a %n' id_key template.txt
600 id_key
600 template.txt

Recursive changes

The -R option changes a directory and everything inside it.

chmod -R u=rwX,go=rX site

The website files have inconsistent permissions. A recursive numeric mode would give files and directories the same bits, so chmod -R 755 would make every file executable. The capital X adds execute only to directories and to files that are already executable for someone, so directories get 755 and files 644. For other combinations, use find -type d and find -type f with -exec chmod.

$ find site -exec stat -c '%A %n' {} +
drwx------ site
drwx------ site/css
-rw-r--r-- site/css/main.css
drwxr-xr-x site/js
-rw-r--r-- site/js/app.js
-rw------- site/index.html
$ chmod -R u=rwX,go=rX site
$ find site -exec stat -c '%A %n' {} +
drwxr-xr-x site
drwxr-xr-x site/css
-rw-r--r-- site/css/main.css
drwxr-xr-x site/js
-rw-r--r-- site/js/app.js
-rw-r--r-- site/index.html

Special permission bits

A fourth leading digit, or the symbols s and t, set the setuid (4), setgid (2), and sticky (1) bits.

chmod 1777 shared
chmod g+s shared
chmod 4755 deploy.sh

Mode 1777 makes a directory writable by everyone while the sticky bit, shown as t, allows users to delete only their own files, like /tmp. The setgid bit on a directory makes new files inherit its group. The setuid bit, shown as s in the owner's execute position, runs a program with the owner's privileges; Linux ignores it on scripts, and it should be used with great care on binaries.

$ mkdir shared
$ chmod 1777 shared
$ chmod g+s shared
$ ls -ld shared
drwxrwsrwt 2 jano jano 4096 Oct 23 12:52 shared
$ chmod 4755 deploy.sh
$ ls -l deploy.sh
-rwsr-xr-x 1 jano jano 32 Oct 23 09:00 deploy.sh

Symbolic links

chmod follows symbolic links given on the command line and changes the target.

chmod 600 link.txt

The mode of notes.txt changed, while the link itself still shows rwxrwxrwx. The permissions of symbolic links are never used on Linux. During a recursive walk, chmod does not follow links it encounters.

$ ln -s notes.txt link.txt
$ chmod 600 link.txt
$ ls -l notes.txt link.txt
lrwxrwxrwx 1 jano jano 9 Oct 23 12:52 link.txt -> notes.txt
-rw------- 1 jano jano 6 Oct 23 09:00 notes.txt

Errors

chmod refuses to change files we do not own and rejects invalid modes.

chmod 666 /tmp/root-file.txt
chmod 9755 deploy.sh

The file belongs to root, so a regular user gets Operation not permitted; sudo chmod is needed. Octal digits range from 0 to 7, so 9755 is not a valid mode.

$ ls -l /tmp/root-file.txt
-rw-r--r-- 1 root root 0 Oct 23 12:52 /tmp/root-file.txt
$ chmod 666 /tmp/root-file.txt
chmod: changing permissions of '/tmp/root-file.txt': Operation not permitted
$ chmod 9755 deploy.sh
chmod: invalid mode: ‘9755’
Try 'chmod --help' for more information.

Best practices for chmod

Source

GNU chmod manual

In this article, we have used the chmod command to change permissions in numeric and symbolic mode, report changes, copy permissions, change directory trees recursively, and set special permission bits.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.