Permissions & sudo
Why you see 'Permission denied' and how to fix it safely using chmod, chown, and sudo.
What you'll learn
- How to read the rwx permission string shown by ls -l
- How to change permissions with chmod using symbolic and octal notation
- When to use sudo — and why you should use it sparingly
Before you start
The core idea: three actions, three audiences
Unix permissions are built from two axes.
Actions (what you want to do):
| Symbol | Name | On a file | On a directory |
|---|---|---|---|
r | read | view contents | list entries (ls) |
w | write | modify contents | create/delete entries |
x | execute | run as a program | enter/traverse (cd) |
Audiences (who you are):
- user (u) — the file’s owner
- group (g) — members of the file’s associated group
- other (o) — everyone else on the system
Every file stores one rwx triplet for each audience — nine bits in total.
Reading the permission string
Run ls -l on any file and the first column is that nine-bit record, preceded by a type character:
ls -l deploy.sh
-rwxr-xr-- 1 alice devs 1024 Jun 5 09:12 deploy.sh
The diagram below breaks that string apart:
The ten-character prefix from ls -l: one type character followed by three rwx triplets (user, group, other). A dash means that bit is unset.
So -rwxr-xr-- means:
- type
-— a regular file (not a directory) - user
rwx— owner can read, write, and execute - group
r-x— group members can read and execute, but not write - other
r--— everyone else can only read
The execute bit (x) on a regular file is what makes it runnable. Without it, the shell refuses to treat it as a program — hence “Permission denied” when you try ./deploy.sh on a freshly written script.
Changing permissions with chmod
chmod (change mode) sets the permission bits. It accepts two notations.
Symbolic notation
Symbolic notation says: for this audience, add or remove these bits.
chmod u+x deploy.sh # give the owner execute permission
chmod go-w deploy.sh # remove write from group and other
chmod a+r report.pdf # add read for all (user, group, other)
The format is [audience][+|-|=][bits]:
- audience:
uuser,ggroup,oother,aall - operator:
+add,-remove,=set exactly - bits: any combination of
r,w,x
Octal notation
Octal notation encodes all nine bits as three digits. Each digit is the sum of the bits that are on for that audience:
| Bit | Value |
|---|---|
r | 4 |
w | 2 |
x | 1 |
So rwx = 4+2+1 = 7, r-x = 4+0+1 = 5, r-- = 4+0+0 = 4, --- = 0.
Two common modes worth memorising:
chmod 644 config.yaml # rw-r--r-- owner rw, everyone else r
chmod 755 deploy.sh # rwxr-xr-x owner rwx, everyone else rx
644 is the default for data files — only the owner can modify them.
755 is the default for programs and directories — anyone can run or enter, only the owner can change.
Changing ownership with chown
Every file has an owner (a user account) and a group. chown changes them:
chown alice deploy.sh # change owner to alice
chown alice:devs deploy.sh # change owner and group
chown :devs deploy.sh # change group only (colon prefix)
You usually need sudo to hand ownership to a different user, because taking ownership of files you do not own is a privilege operation.
The execute bit on directories
On a directory, x means something subtly different from on a file: it grants the right to enter or traverse the directory. Without x on a directory you cannot cd into it, even if you have r (which lets you list the names of entries — but not access them). Most directories should be 755.
Using sudo safely
sudo (superuser do) runs a single command as root — the system’s all-powerful account. Root bypasses all permission checks, so it is how you install packages, edit system config files, or change ownership across users.
sudo chmod 600 /etc/ssh/sshd_config # only root should read this
sudo chown root:root /usr/local/bin/mytool
Guidelines:
sudoone specific command at a time. Avoidsudo bashorsudo suunless you have a clear reason.- Read the command before you run it.
sudo rm -rf /is instant and unrecoverable. - Check whether you actually need root. Many “Permission denied” errors are solved by fixing the file’s permissions or ownership instead.
Putting it together
Scenario: you wrote backup.sh, but running it fails.
ls -l backup.sh
-rw-r--r-- 1 alice staff 342 Jun 5 10:00 backup.sh
The owner triplet is rw- — no x. Fix it:
chmod u+x backup.sh
./backup.sh
Or in octal (owner rw+x, group and other read-only):
chmod 744 backup.sh
Now the shell can execute it.