Navigation & File Permissions¶
Before you can run any tool, you have to be able to move around a Linux filesystem with confidence and read (and set) who is allowed to do what to a given file. Get either wrong and the failure looks identical from the outside — "command not found" or "permission denied" — but the fix is completely different depending on which one it actually is.
TL;DR — in 30 seconds:
- A path is either absolute (starts at
/, always unambiguous) or relative (starts from your current directory,pwd) — know which one you're typing. - Every file has three permission classes (owner / group / others) and three permission bits each
(read / write / execute) —
rwxr-xr--reads left to right, one triplet per class. chmodaccepts the same permissions as either symbolic (u+x) or octal (755) notation — they express the exact same bits, just spelled differently.
1. Moving around — absolute vs. relative paths¶
Every command that takes a path takes either an absolute path (starts with /, unambiguous no matter
where you are) or a relative path (interpreted from your current working directory, shown by
pwd).
flowchart LR
A["A path"] --> B{"Starts with /?"}
B -->|yes| C["Absolute<br/>/home/user/app — always the same file"]
B -->|no| D["Relative<br/>app/config — depends on pwd"]
pwd— print the current working directory (where relative paths are anchored).cd <path>— change directory;cdalone (no argument) returns you to your home directory;cd -returns to the previous directory.ls,ls -l(long format: permissions, owner, group, size, modified time),ls -a(include dotfiles, the hidden files whose name starts with.).- Two relative shorthands appear in almost every path expression:
.(the current directory) and..(the parent directory) —cd ../..moves up two levels. ~expands to your home directory —cd ~/projectsandcd /home/you/projectsare the same command.
2. Reading permissions¶
ls -l shows a ten-character string like -rwxr-xr-- for every entry. The first character is the
file type (- regular file, d directory, l symlink); the remaining nine characters split into
three groups of three:
| Position | Class | Meaning |
|---|---|---|
| 2–4 | Owner (u) | what the file's owning user can do |
| 5–7 | Group (g) | what members of the owning group can do |
| 8–10 | Others (o) | what everyone else can do |
Within each triplet, the three bits are always in the same order: read, write, execute — a
- in a position means that permission is absent.
| Symbol | On a file | On a directory |
|---|---|---|
r |
read the file's contents | list the directory's contents |
w |
modify the file's contents | create/delete/rename entries inside it |
x |
execute the file as a program/script | cd into it, or access files by exact name inside it |
So rwxr-xr-- reads: the owner can read/write/execute; the group can read/execute but not write; everyone
else can only read.
3. Changing permissions — chmod¶
chmod takes the same permission change in either of two notations:
- Symbolic —
chmod u+x script.sh(add execute for the owner),chmod go-w file(remove write from group and others),chmod a+r file(add read for all —a= owner+group+others). - Octal — each triplet collapses to one digit:
r=4,w=2,x=1, summed.chmod 755 script.shsets owner=rwx(4+2+1=7), group=r-x(4+0+1=5), others=r-x(5) — a very common "runnable by me, readable by everyone else" pattern.
| Octal digit | Bits | Meaning |
|---|---|---|
7 |
rwx |
read + write + execute |
6 |
rw- |
read + write |
5 |
r-x |
read + execute |
4 |
r-- |
read only |
0 |
--- |
nothing |
chmod -R <mode> <dir> applies recursively to every file and subdirectory — powerful, and correspondingly
easy to misuse (see the gotchas below).
4. Ownership — chown / chgrp¶
Permissions are checked against an owner and a group, so changing who owns a file changes whose u/
g bits apply to it:
chown <user> <file>— change the owning user.chown <user>:<group> <file>— change owner and group in one call.chgrp <group> <file>— change only the owning group.
Changing ownership itself normally requires elevated privileges (sudo) — you can't hand a file away to
another user as an unprivileged owner.
5. How this connects¶
- This course's next page,
02-text-processing-and-pipes.md— the file-reading permissions this page teaches (do you haveron the file you're about togrep?) are a prerequisite for every pipeline that page builds; acat: Permission deniedmid-pipe is this page'srwxmodel showing up one page later. - Containers (module 03, Containers, the rootless model and its
USER-directive gotcha) — Podman's rootless containers map straight onto the owner/group model taught here: forgettingUSERin a Containerfile means the process inside runs as root by default, the same "which owner actually applies" question §4'schown/chgrpanswers for a file on disk. - Linux (RHEL) (module 09, Linux (RHEL), SELinux) — this page's "permission
denied" gotcha only covers the Unix
rwxmodel; RHEL layers a second, independent permission system (SELinux) on top, where a process can have fully correct Unix bits and still get denied — the two are easy to conflate but diagnosed completely differently.
Common gotchas
- Reaching for
chmod 777to "just make it work." Fix:777grants write to everyone, not just execute to the owner — diagnose which of the nine bits is actually missing (usually justxfor the owner) and set only that one. - Running
chmod -Ron a directory tree without checking what's inside first. Fix: a recursivechmodapplies the exact same mode to files AND directories alike, which is often wrong — a directory typically needsx(to be enterable) even where a file inside it shouldn't have it; check the tree (or usefindwith-type f/-type dto target each separately) before running it wide. - Confusing "permission denied" with "command not found." Fix: "permission denied" means the shell
found the file but you lack the required bit (usually execute, or you're not the owner); "command not
found" means the shell never located the file at all — a
$PATHproblem, not a permissions one. - Assuming a relative path means the same thing in every terminal tab. Fix: relative paths are
resolved against
pwd, which is per-shell-session state — runpwdbefore trusting a relative path you're about to act on.
Check yourself — a file shows rw-r--r--. Can the owner execute it? Can the group write to it?
No to both. The owner's triplet (rw-) has no x, so the owner cannot execute it; the group's triplet
(r--) has no w, so the group cannot write to it. Only the owner can read and write; everyone
(owner, group, others) can read.
Check yourself — what octal number is rwxr-x---, and in plain words, who can do what?
750. Owner = rwx (7, full access), group = r-x (5, read + execute but not write), others = ---
(0, no access at all).
You can defend this when you can read any ls -l permission string cold, convert it to (and from) its
octal form, and explain which single bit is missing when a command fails with "permission denied."