Skip to content

Filesystem Permissions Boot

Filesystem, Permissions & Boot — Quick Reference

Section titled “Filesystem, Permissions & Boot — Quick Reference”

The entire Linux filesystem is a single tree rooted at /. Everything — disks, devices, network mounts — hangs off this tree.

/
├── bin → essential user binaries (ls, cp, bash) — symlink to /usr/bin on modern systems
├── sbin → system binaries (fdisk, mount) — symlink to /usr/sbin on modern systems
├── usr → user programs and libraries
│ ├── bin → most installed programs live here
│ ├── lib → shared libraries for /usr/bin
│ ├── local/ → software compiled/installed outside the package manager
│ └── share/ → architecture-independent data (docs, icons)
├── etc → system-wide configuration files
├── home → user home directories (/home/alice, /home/bob)
├── root → home directory of the root user (not inside /home)
├── var → variable data: logs, databases, mail, pid files
│ ├── log/ → system and service logs
│ ├── cache/ → cached application data
│ └── run/ → runtime data (pid files, sockets)
├── tmp → temporary files, cleared on reboot
├── dev → device files (disks, ttys, null, random)
├── proc → virtual filesystem: live kernel and process info
├── sys → virtual filesystem: hardware and driver info
├── run → runtime data since last boot (replaces /var/run on modern systems)
├── lib → shared libraries for /bin and /sbin
├── mnt → manual mount point for temporary mounts
├── media → auto-mount point for removable media (USB, CD)
├── opt → optional/third-party self-contained software
└── boot → kernel, initrd, bootloader files

plantuml

PathWhat it holds
/etc/passwdUser accounts (username, UID, home, shell)
/etc/shadowHashed passwords (root-readable only)
/etc/groupGroup definitions
/etc/fstabFilesystems to mount at boot
/etc/hostnameMachine hostname
/etc/hostsLocal DNS override
/var/log/syslog or /var/log/messagesGeneral system log
/proc/cpuinfoCPU info (live)
/proc/meminfoRAM info (live)
/proc/<PID>/Everything about a running process

Every file and directory has three permission sets: owner, group, and others.

-rwxr-xr-- 1 alice developers 4096 Jul 10 12:00 script.sh
│└──┴──┴── └───┘ └────────┘
│ │ │ └─ others: r-- (read only)
│ │ └──── group: r-x (read + execute)
│ └─────── owner: rwx (read + write + execute)
└────────── file type: - = file, d = directory, l = symlink

The 9 permission bits as a bit field — orange = owner, blue = group, yellow = others; attr row shows octal value of each bit:

wavedrom

SymbolOctalFile meaningDirectory meaning
r4Read file contentsList directory contents
w2Write / modify fileCreate, delete, rename files inside
x1Execute as programEnter directory (cd)
-0Permission deniedPermission denied
OctalBinarySymbolicMeaning
7111rwxFull access
6110rw-Read + write
5101r-xRead + execute
4100r--Read only
0000---No access
ModeSymbolicTypical use
644rw-r--r--Regular files, configs
755rwxr-xr-xDirectories, executables
600rw-------Private keys, sensitive files
700rwx------Private scripts/directories
777rwxrwxrwxWorld-writable — avoid in production
BitNameOctalEffect
s on owner executeSetUID (SUID)4xxxFile runs as its owner (e.g. sudo, passwd)
s on group executeSetGID (SGID)2xxxFile runs as its group; new files in dir inherit group
t on others executeSticky bit1xxxOnly owner can delete their own files (e.g. /tmp)
Terminal window
chmod 4755 file # set SUID
chmod 2755 dir # set SGID on directory
chmod 1777 /tmp # sticky bit (classic /tmp setup)
ls -l /tmp # shows 'drwxrwxrwt' — t = sticky

Terminal window
# Octal (absolute — sets permissions exactly)
chmod 644 file.txt # rw-r--r--
chmod 755 script.sh # rwxr-xr-x
chmod 600 ~/.ssh/id_rsa # private key
# Symbolic (relative — adds/removes specific bits)
chmod +x script.sh # add execute for all
chmod -w file.txt # remove write for all
chmod u+x script.sh # add execute for owner only
chmod g-w file.txt # remove write from group
chmod o-rwx file.txt # remove all from others
chmod u=rwx,g=rx,o= file.txt # set each class explicitly
# Recursive
chmod -R 755 ./public/ # apply to dir and all contents

Terminal window
chown alice file.txt # change owner to alice
chown alice:developers file # change owner + group
chown :developers file # change group only
chown -R alice:alice ./dir # recursive (all files inside)

Terminal window
chgrp developers file.txt # change group to 'developers'
chgrp -R www-data ./public/ # recursive

chgrp is equivalent to chown :group — use whichever is clearer.


Terminal window
id # current user's UID, GID, and groups
id alice # another user's IDs
whoami # just the username
groups # groups the current user belongs to
cat /etc/passwd # all users (username:x:UID:GID:comment:home:shell)
cat /etc/group # all groups (groupname:x:GID:members)
getent passwd alice # look up a user via NSS (works with LDAP too)
Terminal window
sudo useradd -m -s /bin/bash alice # create user with home dir and bash shell
sudo useradd -m -G sudo,docker alice # add to groups at creation
sudo passwd alice # set password
sudo usermod -aG docker alice # add alice to docker group (-a = append)
sudo usermod -s /bin/zsh alice # change shell
sudo userdel alice # delete user (keep home dir)
sudo userdel -r alice # delete user + home dir
Terminal window
sudo groupadd developers # create a group
sudo groupdel developers # delete a group
sudo gpasswd -a alice developers # add alice to group
sudo gpasswd -d alice developers # remove alice from group
alice:x:1001:1001:Alice Smith:/home/alice:/bin/bash
│ │ │ │ │ │ └── login shell
│ │ │ │ │ └── home directory
│ │ │ │ └── comment / full name (GECOS)
│ │ │ └── primary GID
│ │ └── UID
│ └── password placeholder (actual hash in /etc/shadow)
└── username

Relationship between users, groups, and files:

erd

Terminal window
sudo command # run as root
sudo -u alice command # run as another user
sudo -i # open interactive root shell
sudo !! # re-run last command with sudo
visudo # safely edit /etc/sudoers

/etc/sudoers entry format:

alice ALL=(ALL:ALL) ALL # full sudo access
bob ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx # specific command, no password
%developers ALL=(ALL) ALL # grant to entire group

umask subtracts permissions from newly created files and directories.

Terminal window
umask # show current mask (e.g. 0022)
umask 027 # set new mask for this session
umaskNew file (666 base)New dir (777 base)
022644 (rw-r—r—)755 (rwxr-xr-x)
027640 (rw-r-----)750 (rwxr-x---)
077600 (rw-------)700 (rwx------)

Files default to 666 - umask, directories to 777 - umask (execute is not set on new files).


Power on
┌─────────────────────────────┐
│ BIOS / UEFI │ Hardware init, POST (Power-On Self Test)
│ Finds bootable device │ Reads boot order from firmware settings
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Bootloader (GRUB2) │ Loads kernel + initrd from /boot
│ /boot/grub/grub.cfg │ Shows OS selection menu
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Kernel (vmlinuz) │ Decompresses, initializes hardware
│ + initrd / initramfs │ Temporary root FS with drivers needed to mount real root
└────────────┬────────────────┘
┌─────────────────────────────┐
│ init / systemd (PID 1) │ First process started by the kernel
│ /sbin/init or systemd │ Mounts real root FS, starts services
└────────────┬────────────────┘
┌─────────────────────────────┐
│ systemd targets │ multi-user.target, graphical.target
│ (replaces SysV runlevels) │ Starts all enabled services in parallel
└────────────┬────────────────┘
Login prompt

d2

BIOSUEFI
Partition tableMBR (max 2 TB, 4 partitions)GPT (9.4 ZB, 128 partitions)
Boot filesMBR sector on diskEFI partition (/boot/efi)
Secure BootNoYes (can be disabled)
SpeedSlowerFaster
64-bitNoYes
Terminal window
cat /boot/grub/grub.cfg # GRUB config (auto-generated, don't edit directly)
cat /etc/default/grub # editable GRUB settings
sudo update-grub # regenerate grub.cfg after editing /etc/default/grub
# Useful /etc/default/grub settings
GRUB_TIMEOUT=5 # seconds to show menu
GRUB_DEFAULT=0 # boot first entry by default
GRUB_CMDLINE_LINUX="quiet splash" # kernel parameters

GRUB rescue — if grub drops to a rescue prompt:

Terminal window
# At grub rescue> prompt:
ls # list detected drives: (hd0), (hd0,gpt1), etc.
ls (hd0,gpt2)/ # list files on a partition
set root=(hd0,gpt2)
set prefix=(hd0,gpt2)/boot/grub
insmod normal
normal # boot normally
Terminal window
ls /boot/ # vmlinuz (kernel), initrd.img (initramfs), System.map
uname -r # running kernel version
ls /boot/vmlinuz-* # all installed kernels

The initramfs (initrd.img) is a minimal temporary root filesystem built into a cpio archive. The kernel unpacks it into memory, uses it to load storage drivers and mount the real root partition, then switches to the real root via pivot_root.

Terminal window
lsinitramfs /boot/initrd.img-$(uname -r) | head -30 # inspect initramfs contents
Terminal window
systemctl list-units --type=service # running services
systemctl list-units --state=failed # failed units
systemctl start|stop|restart nginx # manage a service
systemctl enable|disable nginx # start/stop at boot
systemctl status nginx # service status + recent logs
journalctl -b # all logs from current boot
journalctl -b -1 # logs from previous boot
journalctl -u nginx # logs for a specific unit
journalctl -f # follow live logs (like tail -f)
# Boot performance
systemd-analyze # total boot time
systemd-analyze blame # time each unit took
systemd-analyze critical-chain # the slowest path through boot
SysV Runlevelsystemd TargetMeaning
0poweroff.targetShutdown
1rescue.targetSingle-user / recovery
3multi-user.targetCLI, no GUI
5graphical.targetFull desktop
6reboot.targetReboot

graphviz

Terminal window
systemctl get-default # current default target
sudo systemctl set-default multi-user.target # boot to CLI by default
sudo systemctl isolate rescue.target # switch to rescue mode now
# device mountpoint fstype options dump pass
UUID=abc123... / ext4 defaults 0 1
UUID=def456... /boot/efi vfat umask=0077 0 1
UUID=789... /home ext4 defaults 0 2
tmpfs /tmp tmpfs size=1G,noexec 0 0
Terminal window
cat /etc/fstab # view current mounts config
sudo mount -a # mount all entries in fstab (test it)
blkid # list UUIDs and labels of all block devices
lsblk # block device tree

  • ls -la shows the full permission string — read it as [type][owner][group][others].
  • stat file shows octal permissions, owner, group, size, and timestamps in one shot.
  • Prefer chown user:group over running chown and chgrp separately.
  • sudo !! re-runs the last command with sudo — saves retyping long commands.
  • systemd-analyze blame is your first stop when boot feels slow.
  • Never set 777 permissions on files served by a web server — 644 for files, 755 for directories.
  • The sticky bit on /tmp (1777) means any user can write there but cannot delete others’ files.
  • SUID on an executable (chmod 4755) makes it always run as its owner — review carefully before setting.

← Linux