Skip to content
C Codeloom
Linux

Understanding the Linux File System

A practical tour of the Linux file system hierarchy — what /etc, /var, /home, /usr, and friends are actually for, and how paths, mounts, and hidden files work.

·10 min read · By Yash Kesharwani
Beginner 12 min read

What you'll learn

  • How the Linux file system is organised — one tree, no drive letters
  • What each top-level directory (/etc, /var, /home, /usr, /tmp) is for
  • Absolute vs. relative paths, and the special . .. ~ symbols
  • How devices and disks are mounted into the tree
  • How hidden files and dotfiles work

Prerequisites

The Linux file system looks intimidating the first time you cd / and run ls. A wall of cryptic three-letter names appears, none of them familiar. The good news is that the layout is a well-defined standard — the Filesystem Hierarchy Standard (FHS) — and the role of each directory is predictable. Once you know what lives where, the system feels much less mysterious.

This post is a practical tour. The aim is not to memorise every directory but to recognise the half-dozen that you will interact with regularly.

One tree, no drive letters

The single most important fact about the Linux file system: everything is one tree, rooted at /.

There are no C: or D: drives. A second hard disk, a USB stick, a network share, even some kernel data structures — all of them appear as folders somewhere inside /. The location they attach to is called a mount point. We will return to mounting later in the post.

This unified tree is why paths in Linux always look like /home/yash/notes.txt rather than C:\Users\yash\notes.txt. The forward slash separates directories, and the leading / means “start at the root.”

Look around at the top level

Open a terminal and run:

ls /

The output will look something like this:

bin   dev   home   lib    media  opt   root  sbin  sys  usr
boot  etc   lib64  mnt    proc   run   srv   tmp   var

(Slight variations exist between distributions. macOS has a similar-looking top level with additional directories like Applications, Library, System, and Users. The principles below apply on both, though some specific directories like /proc are Linux-only.)

Here is what the ones you will actually use are for.

/home — user files

Every regular user has a directory under /home named after their username, for example /home/yash. This is where your documents, downloads, project folders, and per-user config files live. The shell shorthand ~ expands to your home directory:

cd ~              # go home
echo $HOME        # print the home directory path
ls ~/Downloads    # list a subdirectory of home

On macOS, home directories live under /Users instead of /home — so /Users/yash rather than /home/yash. ~ works identically.

You can do almost all your day-to-day work without leaving your home directory. The rest of the tree mostly belongs to the system.

/etc — system configuration

/etc (pronounced “et-see” or “etcetera”) holds system-wide configuration files. Almost every server program reads its settings from here: /etc/ssh/sshd_config for the SSH server, /etc/nginx/nginx.conf for nginx, /etc/hosts for hostname mappings.

ls /etc
cat /etc/hostname     # the machine's hostname
cat /etc/os-release   # which distribution and version this is

You usually need sudo to edit anything in /etc. These are plain text files, which is one of Linux’s enduring quiet advantages — every config is something you can read with cat and edit with nano.

/var — variable data

/var holds files that change while the system is running: logs, mail spools, package-manager caches, web-server data, database files.

ls /var/log              # system logs
sudo tail /var/log/syslog   # the most recent system messages (Ubuntu/Debian)

If a service has misbehaved, the first place to look is its log in /var/log. macOS uses /var/log similarly, though the main system log is accessed through the log command rather than a single file.

/tmp — temporary files

/tmp is a scratch area. Any user can write here, and the contents are typically cleared on reboot. Don’t put anything important in /tmp — by design, it may vanish without warning.

ls /tmp
echo "scratch" > /tmp/note.txt

/usr — user-installed system programs

Despite the name, /usr does not stand for “user” in the home-directory sense. It holds programs and data that are part of the system but not strictly required to boot it. The structure inside is its own small hierarchy:

  • /usr/bin — most of the commands you run (ls, grep, python3)
  • /usr/lib — libraries those commands depend on
  • /usr/local — software installed manually, outside the package manager
  • /usr/share — read-only architecture-independent data (man pages, icons)

On modern distributions, /bin, /sbin, and /lib at the top level are usually symlinks into /usr. Most beginners never need to think about the distinction.

/bin and /sbin — essential commands

/bin contains essential user commands like ls, cp, cat. /sbin contains essential system administration commands intended for root, like fdisk and reboot.

/root — the root user’s home directory

The administrator account, root, has its home at /root rather than /home/root. You will rarely visit it directly.

/dev — devices

Linux exposes hardware and pseudo-devices as files under /dev. Your first disk is /dev/sda, your terminal is something like /dev/pts/0, and the famous /dev/null is a “black hole” — anything written to it is discarded.

echo "this disappears" > /dev/null

This is genuinely useful for silencing the output of a command you only run for its side effects.

/proc and /sys — kernel windows (Linux only)

/proc and /sys are not real disks at all. They are virtual file systems the kernel populates with information about itself.

cat /proc/cpuinfo       # details about the CPU
cat /proc/meminfo       # memory statistics
cat /proc/uptime        # how long the system has been running

These directories do not exist on macOS. The equivalent information is exposed through different tools (sysctl, vm_stat, uptime).

/mnt and /media — mount points

/mnt is the traditional place to manually mount external drives or network shares. /media is where desktop environments automatically mount removable media like USB sticks. If you insert a flash drive on an Ubuntu desktop, it usually appears as /media/yash/SOMENAME.

Absolute and relative paths

Every path in Linux is either absolute (starts with /) or relative (does not).

/home/yash/notes/todo.txt     # absolute — works from anywhere
notes/todo.txt                # relative — depends on where you are

Two special directory names are universal:

  • . — the current directory
  • .. — the parent directory
cd ..                # go up one level
cd ../..             # go up two levels
ls ./scripts         # equivalent to ls scripts
./run.sh             # run a script in the current directory

The leading ./ for executables is mandatory and intentional — the shell only searches your PATH for command names. ./run.sh says “run the file named run.sh in this directory,” distinguishing it from any system command of the same name.

~ is shorthand for your home directory. It is technically a shell expansion rather than part of a path, but it behaves like one:

cd ~/projects        # /home/yash/projects
ls ~/Downloads       # /home/yash/Downloads

Try it yourself. From your home directory, run cd /var/log, then pwd to confirm where you are, then cd ~- to jump back to your home directory, then cd - to jump back to /var/log. The two-step “I have two directories I keep switching between” pattern is one of the most common shell workflows.

Hidden files

Any file or directory whose name starts with a . (dot) is hiddenls does not show it unless you pass -a.

ls ~          # visible files only
ls -a ~       # everything, including dotfiles

This is purely a naming convention, not a permission. Hidden files typically hold per-user configuration:

  • ~/.bashrc, ~/.zshrc — shell startup files
  • ~/.ssh/ — SSH keys and known hosts
  • ~/.config/ — modern application configs (the XDG standard)
  • ~/.gitconfig — Git’s per-user configuration

Editing your shell’s rc file is one of the first customisations most developers make:

nano ~/.bashrc

Add an alias, save, then reload with source ~/.bashrc.

Mounting: how disks become folders

When you plug in a USB stick or attach a second drive, Linux does not give it a drive letter. Instead, it mounts the drive’s file system at a chosen directory. Everything below that directory is now served by the new disk.

mount                    # list every currently-mounted filesystem
df -h                    # the same info as disk usage, more readable

A typical df -h line looks like:

/dev/sda2       456G   89G  344G  21% /home

This says “the second partition of the first disk is mounted at /home, has 456 GB total, 89 GB used.” The directory /home is a normal-looking folder, but its storage lives on /dev/sda2.

Most of the time, mounting happens automatically. You only mount things by hand when working with servers, custom storage, or unusual setups.

File types: not just files and folders

ls -l shows a single character at the start of each line that tells you what kind of entry it is:

CharacterType
-Regular file
dDirectory
lSymbolic link
cCharacter device (like /dev/tty)
bBlock device (like /dev/sda)
sSocket
pNamed pipe (FIFO)

The two you will see constantly are - (regular file) and d (directory). Symbolic links (l) are the next most common — they are pointers to other files, much like Windows shortcuts but transparent to most programs.

Create one yourself:

cd ~/linux-practice
echo "original" > real.txt
ln -s real.txt link.txt
ls -l                       # link.txt -> real.txt
cat link.txt                # original

File extensions are a hint, not a rule

Unlike Windows, Linux does not generally determine file type from the extension. A file called image.png is treated as a PNG because of its contents, not its name. You can rename notes.txt to notes and cat will read it just fine.

That said, extensions are still helpful for humans and for some tools (your editor’s syntax highlighting, for instance). Convention matters even when it is not enforced.

The file command inspects content directly:

file /etc/hostname        # ASCII text
file /bin/ls              # ELF 64-bit LSB executable
file /usr/share/icons/...png   # PNG image data

Try it yourself. Make a directory ~/fs-tour. Create a file, a symlink to that file, and a subdirectory inside it. Run ls -l and identify the type character at the start of each line. Then run file on each entry. Compare the output.

Recap

You now know:

  • Linux has one file system tree, rooted at /, with no drive letters
  • /home holds your files; ~ is shorthand for your home directory
  • /etc holds system config; /var holds changing data like logs; /tmp is scratch space
  • /usr holds installed programs; /bin and /sbin hold essential commands
  • /dev exposes hardware and pseudo-devices as files; /dev/null is a black hole
  • Paths are absolute if they start with /, relative otherwise; . is here, .. is up
  • Files starting with . are hidden; dotfiles in your home directory hold per-user config
  • Disks are mounted at directories rather than assigned letters
  • File type comes from content, not extension; ls -l shows the type as its first character

Next steps

The last post in this series covers file permissions — the rwx letters and chmod/chown commands you keep seeing in tutorials. After it, you will be fully equipped to read, run, and trust commands you find in documentation.

→ Next: Linux File Permissions Explained

Questions or feedback? Email codeloomdevv@gmail.com.