Skip to content

Linux

chmod Explained: Unix File Permissions Without the Guesswork

10 min read

"Why can't I delete this file?" is the classic first question on Linux. The answer is almost always that you have write access to the file but the directory holding it doesn't let you — and chmod numbers make no sense until you stop reading 644 as an abstract code. The moment you see that every permission digit is just three switches (read, write, execute) summed into one number, the whole system unlocks. This guide goes from that single idea through the octal numbers, the ls -l output, and the everyday defaults like 644 and 755 that keep web servers and home directories doing the right thing.

Every file has three owners: owner, group, others

Every file and directory on Unix carries a small identity card listing who may do what. Three identities matter, and every permission character in a listing appears once per identity:

  • Owner (u) — the user who created the file. Full control is usually assumed here.
  • Group (g) — users who share a group with the owner. Membership is how teams cooperate without opening everything to the world.
  • Others (o) — everyone else on the system. The public.

Attached to each identity sit the three actions: read (r), write (w) and execute (x). Their meaning shifts subtly when the object is a directory instead of a file, and that is where most of the confusion comes from.

The octal numbers: why 4, 2 and 1

chmod's numeric form — the thing everyone actually types — is three octal digits, one per identity, always in the order owner, group, others. Each digit is a sum of action values: read is worth 4, write is worth 2, execute is worth 1. Because those are powers of two (4 + 2 + 1 = 7), every sum from 0 to 7 describes a unique combination, never an ambiguous one:

OctalSymbolicMeaning
7rwxRead, write and execute
6rw-Read and write, no execute
5r-xRead and execute, no write
4r--Read only
3-wxWrite and execute only
2-w-Write only
1--xExecute only
0---No permissions at all

So 644 breaks down as 6 for the owner (read + write), 4 for the group (read only) and 4 for others (read only). The dash is simply "this switch is off": rw- means read and write, execute off.

Reading ls -l output: what -rwxr-xr-- means

Look at the first column of ls -l. It is the ten-character string that intimidates people for no good reason:

$ ls -l
-rw-r--r--  1 mustafa web   18740 Sep 16 09:12 index.html
drwxr-xr-x  2 mustafa web    4096 Sep 16 09:12 assets
-rw-------  1 mustafa web     512 Sep 16 09:12 id_rsa

The first character is the type: - for a regular file, d for a directory, l for a symbolic link. The remaining nine characters are three trios — owner, group, others — each holding the fixed r w x positions, with a dash where a right is missing. So -rw-r--r-- is a file whose owner may read and write while everyone else may only read; drwxr-xr-x is a directory where the owner has full freedom and group plus others may read and traverse.

The Convrs tool regenerates exactly this string from the same checkboxes you would tick by hand, which makes the mapping from "tick r, w, x" to the final text safe to internalize.

chmod 644 vs 755: why files and directories disagree

The two most common chmod arguments in the wild are 644 and 755. Both leave the owner in full control and hand read access to everyone; the difference is the execute bit for group and others. On regular files, execute is a rare, deliberate privilege — you don't want random files to be runnable. On directories it means something different: traversal.

To enter a directory, list its contents, open a file inside it or reach anything nested beneath it, you need the x bit on the directory itself. It is not optional. Hence the administrator's rule of thumb:

  • Files: 644 (rw-r--r--) — readable by everyone, writable by the owner, executable only when it truly must be.
  • Directories: 755 (rwxr-xr-x) — everyone can enter and read, only the owner can change them.

The same defaults power web servers

NGINX and Apache serve files the web user can read, inside directories the web user can traverse: 644 for files, 755 for directories. Private keys stay 600 (owner only), and your ~/.ssh folder should be 700 — owner read/write/execute, nobody else. Apply those and deployed sites break far less often.

Symbolic notation: u+x, g-w, a=r

Octal is great for stating a complete permission set, but for one small surgical change the symbolic form reads better. The syntax is the target (u owner, g group, o others, a all), the operator (+ add, - remove, = set exactly) and the letters r, w, x. A few everyday examples:

$ chmod u+x script.sh        # owner may execute
$ chmod g-w config.php       # group can no longer write
$ chmod a=r notes.txt        # everyone: exactly read, nothing else
$ chmod u=rw,g=r,o= file.txt # owner rw, group r, others none

a=r is a neat trap to know: = sets exactly, so a=r strips execute and write from everyone — it does not merely add read.

Special bits: suid, sgid and the sticky bit

Three extra bits are rarely needed but worth recognizing. setuid (chmod u+s, shown as s in the owner's execute column) makes a program run with the privileges of the file's owner — that is how /usr/bin/passwd writes to a file regular users cannot touch. setgid (chmod g+s) does the same for the group, and on directories it makes new files inherit the parent's group. The sticky bit (chmod +t, shown as t) appears as the very last character: on world-writable directories it means "everyone may create files here, but only the owner may delete their own." /tmp is the canonical example — ls -ld /tmp shows drwxrwxrwt.

Sparingly, please

setuid and setgid are security scissors — one mistake hands unprivileged users elevated powers. In twenty years the average system administrator changes them fewer times than you would think.

When to be careful: the 777 reflex

Stack Overflow answers full of chmod -R 777 are the single biggest source of permission-related security holes on Linux. 777 grants everything to everyone, and -R applies it recursively to every file and directory beneath. One misplaced chmod -R 777 on a web directory leaves your uploaded files world-executable and lets any future script read your backups.

The honest fix is rarely more permissive permissions; it is fewer wrong owners. Run the web server as its own user, own your files with that user, and let 644/755 do the rest. When something reports "permission denied", chmod -R 777 masks the symptom instead of revealing the actual owner or group problem.

Calculate chmod without guessing on Convrs

The Convrs chmod calculator reproduces the same logic as the tables above: tick read, write and execute for the owner, group and others, flip the file/directory switch, and you instantly get the octal value (chmod 644), the symbolic string (-rw-r--r--) and copy buttons for both. Everything runs in your browser, so the numbers you compute for a production server never leave your device.

Buy me a coffee