Linux File Permissions Explained: chmod, chown and umask
On this page
Every file and directory on Linux has an owner, a group, and a set of permissions that decide who can read it, change it, or run it. Permission problems are behind many "it works for me but not on the server" moments, from a web server that cannot read your files to an SSH key that gets refused.
This guide explains how to read permissions, how to change them with chmod and chown, and which values to use for common cases.
Reading ls -l output
$ ls -l
-rw-r--r-- 1 alice alice 1204 Oct 25 09:12 notes.txt
-rwxr-xr-x 1 alice alice 310 Oct 25 09:15 deploy.sh
drwxr-x--- 2 alice www-data 4096 Oct 25 09:20 site
The first column has ten characters. The first is the type: - for a regular file, d for a directory, l for a symbolic link. The other nine are three groups of three:
| Characters | Applies to | Example in drwxr-x--- |
|---|---|---|
| 2 to 4 | User (the owner) | rwx: read, write, execute |
| 5 to 7 | Group | r-x: read and execute |
| 8 to 10 | Others (everyone else) | ---: nothing |
The third and fourth columns are the owner and the group. So site above belongs to alice, members of www-data can enter and list it, and nobody else can.
What r, w and x mean
The letters mean slightly different things for files and directories:
| Permission | On a file | On a directory |
|---|---|---|
r read | View the contents | List the names inside (ls) |
w write | Change the contents | Create, delete and rename files inside |
x execute | Run it as a program | Enter it (cd) and reach files inside |
Two consequences surprise people. First, you can delete a file you cannot write to, if you can write to the directory it is in. Second, a directory needs x to be useful: with r but no x you can see names but not open anything.
Octal notation: 644, 755 and friends
Each permission has a value: read is 4, write is 2, execute is 1. Add them up for each of user, group and others, and you get a three-digit number:
| Digit | Permissions | Digit | Permissions |
|---|---|---|---|
| 7 | rwx (4+2+1) | 3 | -wx (2+1) |
| 6 | rw- (4+2) | 2 | -w- |
| 5 | r-x (4+1) | 1 | --x |
| 4 | r-- | 0 | --- |
So chmod 754 file gives rwxr-xr--. To see a file's permissions as a number on Linux, use stat:
$ stat -c '%a %A %n' deploy.sh
755 -rwxr-xr-x deploy.sh
On macOS the equivalent is stat -f '%OLp %N' deploy.sh.
Typical values
| Mode | Shows as | Typical use |
|---|---|---|
644 | rw-r--r-- | Normal files: web pages, configs, documents |
755 | rwxr-xr-x | Directories and scripts or programs everyone may run |
600 | rw------- | Private files: SSH private keys, .env files, passwords |
700 | rwx------ | Private directories such as ~/.ssh, private scripts |
640 | rw-r----- | Config files a service group must read, others must not |
750 | rwxr-x--- | Directories shared with one group only |
chmod 777. It lets every user and every process on the machine change or replace the file, and on a web server that can turn a small bug into a full compromise. If something only works with 777, the real problem is usually the owner or group, which chown fixes.Symbolic notation
Symbolic mode changes specific bits and leaves the rest alone, which is often safer than setting a full number. The format is who, operator, permissions:
- Who:
u(user),g(group),o(others),a(all three). - Operator:
+adds,-removes,=sets exactly.
$ chmod u+x deploy.sh # owner may execute
$ chmod +x deploy.sh # everyone may execute (respecting umask)
$ chmod go-w notes.txt # remove write for group and others
$ chmod o= secrets.txt # others get nothing
$ chmod u=rw,go=r notes.txt # same as 644
$ chmod g+w,o-rwx shared/ # several changes at once
Changing permissions recursively
chmod -R applies a mode to a directory and everything inside it. Be careful with numbers here: chmod -R 755 site/ makes every file executable, and chmod -R 644 site/ removes x from directories so nobody can enter them.
A capital X solves this. It adds execute only to directories, and to files that already have execute for someone:
$ chmod -R u=rwX,go=rX site/
That gives directories 755 and ordinary files 644 in one command. The other common approach uses find to treat files and directories separately (see the find guide):
$ find site -type d -exec chmod 755 {} +
$ find site -type f -exec chmod 644 {} +
chmod or chown, especially with sudo. A stray space, as in sudo chmod -R 755 / var/www, changes your entire system and can break sudo and SSH. Never run recursive changes on /, /etc, /usr or your home directory as a whole.Changing owner and group: chown and chgrp
Only root can give a file to another user, so these usually need sudo:
$ sudo chown alice notes.txt # change owner
$ sudo chown alice:www-data notes.txt # change owner and group
$ sudo chown :www-data notes.txt # change group only
$ sudo chown -R www-data:www-data /var/www/site # whole tree
$ chgrp developers project/ # change group (you must be a member)
A regular user can change a file's group with chgrp to any group they belong to; run id to see yours.
umask: default permissions for new files
New files do not start with full permissions. Programs usually ask for 666 for files and 777 for directories, and the umask removes bits from that. The common default umask is 022, which removes write for group and others:
$ umask
0022
$ touch newfile; mkdir newdir
$ ls -ld newfile newdir
-rw-r--r-- 1 alice alice 0 Oct 25 09:30 newfile
drwxr-xr-x 2 alice alice 4096 Oct 25 09:30 newdir
With umask 077, new files are 600 and directories 700, private to you. umask 002 gives 664 and 775, common on systems where each user has their own group and teams share directories. Set it in ~/.bashrc or ~/.profile to make it stick (see the startup files guide). umask -S shows the result in symbolic form.
setuid, setgid and the sticky bit
There is a fourth, leading octal digit for three special permissions:
| Bit | Value | Shows as | Effect |
|---|---|---|---|
| setuid | 4 | rwsr-xr-x | A program runs with the permissions of its owner, not the user who started it |
| setgid | 2 | rwxrwsr-x | On a directory: new files inherit the directory's group |
| sticky | 1 | rwxrwxrwt | On a directory: users can delete only their own files |
You see these on standard systems already:
$ ls -ld /tmp /usr/bin/passwd
drwxrwxrwt 18 root root 4096 Oct 25 09:31 /tmp
-rwsr-xr-x 1 root root 68248 Mar 23 2023 /usr/bin/passwd
/tmp is world-writable but sticky, so users cannot delete each other's files. passwd is setuid root so ordinary users can update the password database. A capital S or T means the special bit is set but the execute bit underneath is not, which is usually a mistake.
The setgid bit is the one you are most likely to set yourself, for a shared team directory:
$ sudo chgrp developers /srv/project
$ sudo chmod 2775 /srv/project # or: chmod g+s /srv/project
GNU chmod keeps the setgid bit on directories when you later use a three-digit mode like 755; remove it explicitly with chmod g-s.
sudo rules when a user needs to run one command as root.Quick reference
ls -l: show permissions, owner and group.stat -c '%a %n' file: permissions as a number (Linux).chmod 644 file,chmod 755 dir,chmod 600 key: the common modes.chmod u+x script.sh: make a script executable for you.chmod -R u=rwX,go=rX dir: sane recursive permissions.sudo chown user:group file: change owner and group.umask 022: new files 644, directories 755.chmod g+s dir: new files inherit the directory's group.