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. 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. That is why you see “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 = 7r-x= 4+0+1 = 5r--= 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.
The r bit 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.
That 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
rwxtriplet for each of three audiences: user (owner), group, other — whichls -lshows after a leading type character (-file,ddir,llink). - On a file
r/w/xmean 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, wherer=4 w=2 x=1sum per audience. Use644for data files,755for programs and directories, and never777. chownchanges the owner/group, which usually needssudo. Andsudoruns one command as all-powerful root — use it on a single, read-and-understood command, never a sprawling pipeline, and check first whether achmod/chownwould 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? 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.
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.