Every Linux file has three sets of permissions, read (r), write (w) and execute (x), for its owner, its group and everyone else. chmod changes them, either as a three-digit number where read = 4, write = 2 and execute = 1 (so chmod 644 file means owner 6 = read + write, group and others 4 = read) or symbolically, as in chmod u+x script.sh.
The examples below are real output from Ubuntu 22.04 (GNU coreutils 8.32), run in WSL. macOS uses the same permission model and accepts the same chmod modes.
How to read ls -l output
ls -l
Example output:
-rw-r--r-- 1 alex alex 18 Oct 26 12:00 deploy.sh
-rw-r--r-- 1 alex alex 3 Oct 26 12:00 notes.txt
drwxr-xr-x 2 alex alex 4096 Oct 26 12:00 site
Take the first line apart, left to right:
| Part | Value | Meaning |
|---|---|---|
| File type | - | Regular file. d = directory, l = symbolic link. |
| Owner permissions | rw- | The owner can read and write, not execute. |
| Group permissions | r-- | Members of the file's group can read. |
| Others permissions | r-- | Everyone else can read. |
| Hard links | 1 | Number of names pointing at this file. |
| Owner | alex | The user who owns the file. |
| Group | alex | The file's group (often a personal group with the same name). |
| Size | 18 | Bytes. Add -h for 1K, 234M style sizes. |
| Timestamp, name | Oct 26 12:00 deploy.sh | Last modification time and file name. |
A dash in a permission slot means that permission is off. To see a directory's own permissions rather than its contents, use ls -ld site.
What read, write and execute mean for files and folders
The letters mean different things on a directory, which is the source of most confusion:
| Letter | On a file | On a directory |
|---|---|---|
r (4) | Read the contents | List the names inside it |
w (2) | Change the contents | Create, delete and rename files inside it |
x (1) | Run it as a program | Enter it and access files inside it |
Two consequences: deleting a file depends on write permission on the directory, not on the file. And a directory needs x to be usable at all, which is why directories are usually 755 while ordinary files are 644.
How octal permissions like 755 and 644 work
Each digit is the sum of the permissions for one class, in the order owner, group, others. Read is 4, write is 2, execute is 1:
| Mode | Owner | Group | Others | ls -l shows | Typical use |
|---|---|---|---|---|---|
755 | 7 = 4+2+1 (rwx) | 5 = 4+1 (r-x) | 5 = 4+1 (r-x) | rwxr-xr-x | Directories, scripts, programs |
644 | 6 = 4+2 (rw-) | 4 (r--) | 4 (r--) | rw-r--r-- | Ordinary files, web pages |
600 | 6 = 4+2 (rw-) | 0 (---) | 0 (---) | rw------- | Private keys, files with passwords |
700 | 7 = 4+2+1 (rwx) | 0 (---) | 0 (---) | rwx------ | Private directories such as ~/.ssh |
To decode any digit, subtract the largest values that fit: 6 is 4 + 2, read and write. 5 is 4 + 1, read and execute. 3 is 2 + 1, write and execute (rare in practice). On Linux, stat -c '%a %A %n' file prints a file's current mode both ways, for example 600 -rw------- notes.txt.
The chmod manual allows a fourth, leading digit for special bits: 4 = setuid, 2 = setgid, 1 = sticky. You see them in ls -l as an s or t in place of x. On the test system, /usr/bin/passwd shows -rwsr-xr-x (setuid, so it runs with its owner's rights) and /tmp shows drwxrwxrwt (sticky, so users can only delete their own files in it). A three-digit mode such as 755 is the same as 0755.
How to use chmod with symbolic mode (u+x, go-w)
Symbolic mode changes specific bits and leaves the rest alone, so you don't need to know the current mode. The format is who, operator, permissions:
- Who:
uowner (user),ggroup,oothers,aall three. - Operator:
+adds,-removes,=sets exactly. - Permissions: any of
r,w,x.
chmod u+x deploy.sh # owner may run it
chmod go-w deploy.sh # group and others may not write
chmod a=r notes.txt # everyone read-only: r--r--r--
chmod u=rw,go= notes.txt # same as 600; clauses separated by commas
The classic case is a script that won't run. Before:
$ ls -l deploy.sh
-rw-r--r-- 1 alex alex 18 Oct 26 12:00 deploy.sh
$ ./deploy.sh
bash: line 1: ./deploy.sh: Permission denied
After chmod u+x deploy.sh, ls -l shows -rwxr--r-- (744) and the script runs. If you leave out the "who" letter, as in chmod +x, chmod applies the change to all classes except bits masked by your umask; with the common umask of 0022, that means owner, group and others all get x.
To change a whole tree, add -R. Capital X adds execute only to directories (and files that are already executable for someone), which makes this the safe way to fix a folder of mixed files:
chmod -R u=rwX,go=rX project/
That gives directories 755 and ordinary files 644 in one command. chmod -R 755 project/ would mark every file executable instead.
How to change the owner with chown
Permissions only help if the right user owns the file. chown changes the owner, the group, or both:
sudo chown alex notes.txt # owner only
sudo chown alex:www-data notes.txt # owner and group (no spaces around :)
sudo chown :www-data notes.txt # group only, like chgrp
sudo chown -R alex:alex project/ # whole tree
Regular users cannot give their files away, so you need sudo. Without it you get:
chown: changing ownership of 'notes.txt': Operation not permitted
Why chmod 777 is the wrong fix
777 is rwxrwxrwx: every user on the system can change or replace the file, and anything inside a 777 directory can be deleted or swapped by any user. On a web server, that includes the web server's account, so a flaw in any site or plugin can rewrite your files. It also makes some programs refuse to work: ssh "will simply ignore a private key file if it is accessible by others", and the SSH server rejects keys in files or folders others can write to.
When "Permission denied" appears, work out which user needs which access instead:
- Find who is trying: your account (
whoami) or a service account such aswww-data. - Check the file and every directory above it:
namei -l /full/path/to/filelists owner and mode for each step. - Fix the narrowest thing: change ownership with
chown, add the user to the file's group and grantg+w, or add just the missing bit with symbolic mode.
If permissions still don't behave
- Files on Windows or FAT drives. On WSL's
/mnt/c(default settings),chmod 600succeeded silently on our test file andls -lstill showed-rwxrwxrwx. USB sticks formatted as exFAT or FAT32 have no Unix permissions either. Keep scripts and keys inside the Linux file system (for WSL, your home directory). Installing WSL covers where those files live. - The file system is mounted read-only or
noexec. Runmount | grep ' on /mount/point 'and look forroornoexecin the options. - ACLs or SELinux. A
+after the permission string (-rw-r--r--+) means extra access-control entries; read them withgetfacl file. A.there indicates an SELinux security context.
For SSH keys specifically, see how to generate an SSH key, which covers the 600 and 700 modes ssh expects.
Frequently asked questions
- What does chmod +x do?
- chmod +x file adds execute permission. With no u, g, o or a in front, chmod applies the change to everyone except bits blocked by your umask, so with the common umask 022 the file becomes executable for owner, group and others. Use chmod u+x to make it executable for the owner only.
- What is the difference between 755 and 775?
- The middle digit, which is the group's permissions. 755 gives the group read and execute (5 = 4 + 1). 775 also gives the group write (7 = 4 + 2 + 1), so any member of the file's group can modify it. Use 775 for shared folders where a team group needs to write; use 755 otherwise.
- Why do I get Permission denied even though the file is 644?
- 644 lets everyone read the file, but to reach it you also need execute (search) permission on every directory in its path. A file inside a 700 directory owned by someone else is unreachable whatever its own mode. Check each directory with ls -ld, or namei -l /full/path/to/file, which lists the permissions of every component.
- Do chmod permissions work on Windows drives?
- Not in the normal way. NTFS and FAT drives use Windows permissions, In a default WSL setup, for example, chmod 600 on a file under /mnt/c exits without an error, but ls -l still shows -rwxrwxrwx afterwards. Drives formatted as exFAT or FAT32 behave similarly because those file systems have no Unix permissions. Store files whose Linux permissions matter, such as SSH keys and scripts, on a Linux file system.