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 last chapter ended by walking you into a wall: you step onto a real server, try something ordinary, and get Permission denied. This lesson dismantles that wall. The secret is that every file carries a tiny nine-bit record of who may read, write, and run it — and once you can read that record at a glance and change it on purpose, the error stops being a mystery and becomes a checklist.
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.
In one breath
Every file stores nine permission bits — an rwx triplet for each of three audiences: user (owner), group, other — which ls -l shows after a leading type character (- file, d dir, l link). On a file r/w/x mean read/modify/run; on a directory they mean list/create-delete/enter (cd). Change them with chmod, either symbolically (chmod u+x deploy.sh) or in octal where r=4 w=2 x=1 sum per audience — 644 for data files, 755 for programs and directories, and never 777. chown changes the owner/group (usually needs sudo). And sudo runs one command as all-powerful root — use it on a single, read-and-understood command, never a sprawling pipeline, and check first whether a chmod/chown would solve it without root at all.
Practice
Before the quiz, debug a real error. You wrote migrate.sh, run ./migrate.sh, and get Permission denied. Walk the diagnosis: which two commands do you run first to see why, what specific bit are you hunting for in the ls -l output, and what is the single chmod (give it in both symbolic and octal) that fixes it without granting anyone else write access?
Quick check
A question to carry forward
Permissions decided what a file will let you do. But the instant you actually run one — your deploy.sh, now that it has its execute bit — it stops being a file at all and becomes a living process, and a whole new set of questions opens up. What if it hangs and never returns? What if it quietly eats all the machine’s memory? What if it needs to keep running for an hour and you want your prompt back to do other work in the meantime? A file just sits there; a running program has to be watched, controlled, and sometimes killed. Seeing exactly what is running, stopping what is stuck, and pushing slow work into the background is the next lesson.