skip to content

On Linux, `ls -l` prints a file's mode as a string such as `-rw-r--r--`. Explain what each part of that string means and what the equivalent octal number is.

level: juniorimportance: must knowfreq 82%

answer

  1. ten characters, not nine
  2. first one is the type
  3. three triads: owner, group, others
  4. r is 4, w is 2, x is 1
  5. rw-r--r-- adds up to 644

basics

~20 s

The first character gives the file type; the next nine are three rwx triads for owner, group and others. So -rw-r--r-- is a regular file the owner can read and write while everyone else can only read: octal 644.

solid answer

~40 s

That string is ten characters, not nine. The first is the file type — `-` for a regular file, `d` for a directory, `l` for a symlink. The remaining nine split into three triads of `rwx`: permissions for the **owner**, for the file's **group**, and for **others** (everyone else). A dash means the bit is off. Each triad maps to an octal digit with r=4, w=2, x=1, so `rw-` is 6, `r--` is 4, and `-rw-r--r--` is mode 644. I can set the same thing two ways: numerically with `chmod 644 file`, or symbolically with `chmod u=rw,go=r file`. The symbolic form is relative when you use `+` or `-` (`chmod g+w`) and absolute when you use `=`.

code

bash · 7 lines
bash
umask 022
touch /tmp/demo.txt
ls -l /tmp/demo.txt
chmod 640 /tmp/demo.txt
ls -l /tmp/demo.txt
chmod u=rw,g=r,o= /tmp/demo.txt
stat -c '%A %a %U %G' /tmp/demo.txt

go deeper

for a junior

Be able to read a long listing out loud: name the type character, then the owner, group and other triads, and convert to octal on the spot with 4-2-1. Know that chmod takes both 644 and u=rw,go=r.

for a middle

Explain that the mode plus the owning UID and GID live in the inode, that = in symbolic form is absolute while +/- are relative, and that write on a file is not the right to unlink it.

for a senior

Show judgment about which notation to use in automation: numeric when you want a guaranteed end state, symbolic when you are adjusting one bit on files whose current modes vary. Mention that + or . after the mode signals ACLs or a security context.

for a principal

Own the standard: define what modes application files, config and data directories should carry as a written baseline, and decide how that baseline is asserted and audited across a fleet rather than fixed by hand per host.

## The ten characters A long listing line starts with ten characters, for example `-rw-r--r--`. It is easy to miscount them as nine permission bits; there are nine, but they are preceded by a **file-type character**: | Char | Type | |---|---| | `-` | regular file | | `d` | directory | | `l` | symbolic link | | `c` | character device | | `b` | block device | | `s` | socket | | `p` | named pipe (FIFO) | Everything after that first character describes access. ## Three triads, three classes The nine bits are three groups of three, always in the order `rwx`: ``` - rw- r-- r-- ^ ^ ^ ^ | | | +-- others: everyone else | | +------- group: members of the file's group | +------------ owner (the "user" class) +---------------- file type ``` A dash in a slot means that bit is off. On a **regular file** the bits mean: - `r` — read the contents. - `w` — modify the contents (truncate, append, overwrite). It does **not** grant the right to delete the file; deleting is a change to the directory that contains the name, so it is governed by that directory's permissions. - `x` — execute the file as a program. For a script the kernel also needs the interpreter line to be valid; without `x` you get `Permission denied` even if you can read the file perfectly well. On a **directory** the same three letters mean something different — read lists the names, execute lets you traverse into it and resolve a name — which is why `755` on a directory is normal and `755` on a data file is usually a mistake. ## The octal encoding Each triad is a three-bit number, written as one octal digit: ``` r = 4 w = 2 x = 1 rwx = 4+2+1 = 7 rw- = 4+2 = 6 r-x = 4+1 = 5 r-- = 4 = 4 ``` So `-rw-r--r--` is `644`, `-rwxr-xr-x` is `755`, `-rw-------` is `600`, and `-rw-r-----` is `640`. You will sometimes see four digits (`0644`): the leading digit carries the set-user-ID, set-group-ID and sticky bits, which are a separate topic — a plain `0` means none of them are set. ## Setting the bits: numeric vs symbolic `chmod` accepts both notations, and the difference matters: - **Numeric** — `chmod 640 file` sets the entire mode at once. It is absolute: whatever the file had before is replaced. - **Symbolic** — `chmod g+w file` adds one bit; `chmod o-r file` removes one; `chmod u=rw,go=r file` assigns each class exactly. The operators are `+` (add), `-` (remove) and `=` (set exactly), and the class letters are `u` (user/owner), `g` (group), `o` (others) and `a` (all three). Symbolic form is the safer choice when you want to change one thing without disturbing the rest — `chmod +x script.sh` adds the execute bit and leaves the read/write layout alone. Numeric form is the clearer choice when you want a known end state, because it does not depend on what was there before. ## Where the mode actually lives The nine bits, plus the owning user ID and group ID, are stored in the file's inode — not in the filename and not in a separate database. `stat` shows both renderings at once: ``` $ stat -c '%A %a %U %G' /etc/passwd -rw-r--r-- 644 root root ``` Because the numbers stored are UIDs and GIDs, `ls -l` has to look up names for display; a file owned by a deleted account simply shows the bare number. ## Two extra characters you may see GNU `ls -l` sometimes appends an eleventh character after the mode: a `+` means the file carries an ACL, and a `.` means it has a security context and no other alternate access method. Both point at access-control systems layered on top of the nine bits, and both are separate topics — but seeing them tells you the nine bits are not the whole story for that file. ## What interviewers are checking They want to know you can read a listing without guessing: identify the type, name the three classes in order, convert to octal in your head, and say plainly that `w` on a file is not permission to delete it.

  • If a file's mode is 644 and I own it, can I delete it?
    That depends on the directory, not on the file. Removing a name is a modification of the containing directory, so you need write and execute permission on that directory. A file you cannot write at all can still be deleted if you can write its directory, and a file you own with mode 644 is undeletable if the directory denies you write.
  • Why does a shell script fail with Permission denied even though I can read it?
    Reading and executing are separate bits. Running a file as a program requires the execute bit for whichever class applies to you; `chmod +x script.sh` adds it. You can always sidestep it by invoking the interpreter explicitly — `bash script.sh` only needs read permission, because in that case the shell is the program being executed, not the script.
  • What does the fourth, leading octal digit in a mode like 0644 represent?
    It carries the three special bits — set-user-ID, set-group-ID and the sticky bit — above the nine ordinary permission bits. A leading `0` means none are set, which is the normal case. When one is set, `ls -l` shows it as an `s` or `t` in place of an execute character rather than adding a column.

Think of the nine bits as three separate door keys cut for three named groups of people — the owner, the group, and everyone else — rather than one lock that opens progressively wider.

saying these in an interview costs you the question

  • Counting nine characters and mis-reading the type character as a permission
  • Claiming write permission on a file lets you delete it
  • Saying 777 is a reasonable fix for a permission error
  • Thinking the three triads accumulate, so group permissions add to the owner's
  • Believing the mode is stored in the filename or in a central permissions file

context