Every Linux server you will ever log into has the same directory structure. /etc always holds configuration. /var/log always holds logs. /proc always shows running processes. This predictability is not accidental — it comes from the Filesystem Hierarchy Standard (FHS), a specification that every major Linux distribution follows.
When a Hotstar engineer gets paged at 2 AM because the streaming API is returning errors, they do not hunt for log files. They go straight to /var/log/app/ because that is where logs live. They check /etc/nginx/ for configuration because that is where config lives. Understanding the FHS means any Linux server is immediately familiar.
Why It Matters
The Linux filesystem is the foundation underneath everything a DevOps engineer manages. Container images are Linux filesystems packaged differently. Kubernetes mounts volumes at specific paths inside containers. Ansible manages files at specific paths on remote hosts. CI/CD scripts read from and write to specific directories.
Misunderstanding paths is the source of a surprising number of production issues: a deployment script that works locally but fails in CI because relative paths resolve differently, a cron job that cannot find a binary because /usr/local/bin is not in cron's PATH, a Dockerfile that references the wrong path and silently copies nothing.
Core Principles
The Filesystem Hierarchy Standard — what lives where:
/+----+-- bin/ Essential binaries (ls, cp, mv, bash)| +-- sbin/ System binaries (fdisk, iptables, sshd)| +-- etc/ Configuration files — all of them| +-- var/ Variable data (logs, databases, spool)| | +-- log/ Application and system logs| | +-- run/ PID files and runtime data| +-- tmp/ Temporary files (cleared on reboot)| +-- home/ User home directories| +-- root/ Root user home directory| +-- proc/ Virtual FS: live kernel and process data| +-- sys/ Virtual FS: kernel hardware interface| +-- dev/ Device files (disks, terminals, null)| +-- mnt/ Manual mount points| +-- media/ Auto-mount points (USB, CD)| +-- opt/ Optional/third-party software| +-- usr/ User programs| | +-- bin/ Non-essential binaries| | +-- lib/ Libraries| | +-- local/ Locally installed software| +-- lib/ Shared libraries+----+-- boot/ Kernel and bootloader filesAbsolute vs relative paths:
An absolute path starts from root (/) and is always unambiguous:
/etc/nginx/nginx.conf # always this exact file/var/log/app/error.log # always this exact file/home/deploy/.ssh/id_ed25519 # always this exact fileA relative path is resolved from the current working directory:
./deploy.sh # deploy.sh in current directory../config/app.yaml # config/app.yaml one level uplogs/error.log # logs/error.log in current directoryCommon MistakeRelative paths in scripts, cron jobs, and systemd units almost always cause failures because the working directory is not what you expect. Always use absolute paths in automation.
The /proc filesystem — reading live kernel data:
/proc is not a real filesystem on disk. The kernel generates its contents on demand. Every running process has a directory /proc/PID/ containing live information:
cat /proc/1/cmdline # command that started PID 1ls -la /proc/1234/fd/ # open file descriptors of PID 1234cat /proc/meminfo # live memory statisticscat /proc/cpuinfo # CPU informationcat /proc/sys/net/ipv4/ip_forward # current kernel parameter valueStep-by-Step Lab
Milestone 1 — Navigate the filesystem confidently
## Check where you arepwd## /home/youruser ## Go to root and explorecd /ls -la ## Go to etc and look at what is configuredcd /etcls -la | head -30 ## Use absolute path from anywherels -la /var/log/ ## Go home quicklycd ~ # or just: cdpwd## /home/youruser ## Go back to previous directorycd /etccd -## returns to /home/youruserMilestone 2 — List files with useful flags
## Long format with human-readable sizesls -lh /var/log/ ## Show hidden files (dotfiles)ls -la ~## .bashrc .ssh .profile are all hidden (start with .) ## Sort by modification time, newest firstls -lt /var/log/ ## Recursive listingls -R /etc/ssh/ ## Show directories onlyls -d /etc/*/Milestone 3 — Create, copy, move, and delete
## Create directoriesmkdir -p /tmp/lab/configs/nginx # -p creates intermediate dirs ## Create filestouch /tmp/lab/app.logtouch /tmp/lab/{file1,file2,file3}.txt # brace expansion creates 3 files ## Copycp /etc/hosts /tmp/lab/hosts.backupcp -r /etc/ssh/ /tmp/lab/ssh-backup/ # -r for directories ## Move (also used to rename)mv /tmp/lab/file1.txt /tmp/lab/renamed.txt ## Removerm /tmp/lab/file2.txtrm -r /tmp/lab/ssh-backup/ # -r for directories ## ALWAYS double-check before rm -rfrm -rf /tmp/lab/ # removes everything, no recoverySecurity
rm -rfwith a variable (rm -rf $DIRNAME/) is extremely dangerous. If the variable is empty, this becomesrm -rf /. Always quote and validate variables before using them in delete commands.
Milestone 4 — Find files efficiently
## Find by name (case sensitive)find /etc -name "nginx.conf" ## Find by name (case insensitive)find /var/log -iname "*.log" ## Find files modified in the last 24 hoursfind /var/log -mtime -1 -type f ## Find files larger than 100MBfind / -size +100M -type f 2>/dev/null ## Find files with specific permissionsfind /home -name ".ssh" -type d -perm 700 ## Find and execute a command on each resultfind /tmp -name "*.tmp" -mtime +7 -delete## Deletes .tmp files older than 7 days ## Faster search using index (update index first with: sudo updatedb)locate nginx.conf ## Find which binary a command useswhich python3## /usr/bin/python3 whereis nginx## nginx: /usr/sbin/nginx /etc/nginx /usr/share/man/man8/nginx.8.gzMilestone 5 — View file contents
## Print entire filecat /etc/hosts ## View large files page by page (q to quit, /pattern to search)less /var/log/syslog ## First 20 lineshead -n 20 /var/log/nginx/access.log ## Last 50 linestail -n 50 /var/log/nginx/error.log ## Follow a log file live (Ctrl+C to stop)tail -f /var/log/app/application.log ## Follow and show last 100 lines firsttail -f -n 100 /var/log/app/application.log ## View file infofile /bin/bash # shows: ELF 64-bit executablestat /etc/hosts # shows inode, size, timestamps, permissionsMilestone 6 — Check disk usage
## Disk space by filesystemdf -h## Filesystem Size Used Avail Use% Mounted on## /dev/xvda1 20G 12G 7.5G 62% / ## Disk usage of a directorydu -sh /var/log/## 2.3G /var/log/ ## Find the biggest directoriesdu -sh /var/* | sort -rh | head -10 ## Find largest files in /var/logfind /var/log -type f -exec du -sh {} + | sort -rh | head -10Milestone 7 — Work with links
## Create a symbolic link (soft link)ln -s /opt/app/current/bin/app /usr/local/bin/app## Now you can run 'app' from anywhere ## Update a symlink to point to new versionln -sf /opt/app/v2.0/bin/app /usr/local/bin/app## -f forces overwrite of existing link ## Create a hard linkln /etc/hosts /tmp/hosts-hardlink## Both point to same inode — same file, two names ## Read where a symlink pointsreadlink /usr/local/bin/app## /opt/app/current/bin/app ## Find broken symlinksfind /usr/local/bin -xtype l## Lists symlinks whose target does not existCommon Mistakes
| Mistake | Problem | Fix |
|---|---|---|
| Using relative paths in cron | Cron runs from /, relative paths break |
Always use absolute paths |
rm -rf with unquoted variable |
Variable empty = rm -rf / = disaster |
Quote vars, validate before delete |
Confusing /tmp with persistent storage |
/tmp is cleared on reboot |
Use /var/ for persistent data |
Editing files in /proc directly |
/proc is a virtual filesystem |
Use sysctl -w to change kernel params |
Troubleshooting
| Symptom | First Command | What to Look For |
|---|---|---|
| Disk full, cannot write files | df -h |
Filesystem at 100% Use% |
| Cannot find a file | find / -name filename 2>/dev/null |
Output shows path |
| Not sure which binary runs | which commandname |
Full path to binary |
| File exists but app cannot read it | ls -la filename |
Permission denied for relevant user |
| Symlink not working | readlink -f symlinkname |
Target path does not exist |
Tip
ls -lh(lowercase L) is the most useful listing command in production. It shows permissions, owner, size in human-readable format, and modification time — everything you need to diagnose a file issue.
Remember
/procand/sysare virtual filesystems. They have no files on disk. The kernel generates their contents in memory on demand. Changes to/proc/sys/viasysctl -ware lost on reboot — make permanent changes in/etc/sysctl.conf.