Linux is a multi-user system. Permissions control who can read, write, or execute a file. Every single file and directory has an owner, a group, and a set of permission bits.
Reading ls -l Output
When we run ls -l, we get something like this:
-rw-r--r-- 1 manish developers 4096 Mar 15 10:30 deploy.sh
Let’s break that down: the first character is the file type (- for file, d for directory, l for symlink). The next 9 characters are the permission bits.
So rw-r--r-- means: owner can read+write, group can read, everyone else can read.
Numeric (Octal) Permissions
Each permission has a numeric value: r=4, w=2, x=1. We add them up per group.
chmod 755 deploy.sh # rwxr-xr-x (owner: all, group: read+exec, others: read+exec)
chmod 644 config.yml # rw-r--r-- (owner: read+write, everyone else: read)
chmod 600 secret.key # rw------- (only owner can read+write)
chmod 700 scripts/ # rwx------ (only owner has full access)
Common combos to memorize: 755 for scripts/directories, 644 for regular files, 600 for secrets.
Symbolic Permissions
We can also use letters with +, -, and =.
chmod +x deploy.sh # add execute for everyone
chmod u+w config.yml # add write for owner (u=user/owner)
chmod g-w shared.txt # remove write from group
chmod o= secret.key # remove all permissions for others
chmod u=rwx,g=rx,o= dir/ # set exact permissions
The letters: u = owner, g = group, o = others, a = all.
Changing Ownership
chown manish file.txt # change owner
chown manish:developers file.txt # change owner AND group
chown -R manish:www-data /var/www # recursive ownership change
chgrp developers project/ # change group only
umask — Default Permissions
When we create a new file, umask determines the default permissions. It works by subtracting from the maximum.
umask # show current mask (typically 0022)
umask 0027 # set new mask
# With umask 0022:
# new files → 666 - 022 = 644 (rw-r--r--)
# new dirs → 777 - 022 = 755 (rwxr-xr-x)
Special Permission Bits
These come up in interviews but are rarely changed day-to-day.
- SUID (4xxx) — file runs as the file’s owner, not the user running it. Example:
/usr/bin/passwdruns as root so users can change their own password. - SGID (2xxx) — on a directory, new files inherit the directory’s group. Great for shared project folders.
- Sticky bit (1xxx) — on a directory, only the file owner can delete their files.
/tmphas this so users can’t delete each other’s temp files.
chmod 4755 special_script # set SUID
chmod 2775 shared_dir/ # set SGID
chmod 1777 /tmp # set sticky bit (already set on /tmp)
ls -ld /tmp # drwxrwxrwt ← the "t" means sticky bit
In simple language, permissions are just a 3x3 grid: three groups of people (owner, group, others) each get three toggles (read, write, execute). That’s the whole system.