Navigating the Filesystem
Summary: in this tutorial, you will learn learn the linux directory structure, essential navigation commands (pwd, cd, ls), and absolute vs relative paths.
Navigating the Filesystem
Everything in Linux is organized in a hierarchical tree-like filesystem. Before you can do anything useful—edit files, run programs, analyze logs—you need to know how to navigate this structure. Think of the filesystem as a building: directories (folders) are rooms, files are objects in those rooms, and paths are the directions to get there.
Why filesystem navigation matters:
- Foundation of everything: Every command operates on files and directories
- Context awareness: Understanding where you are prevents accidental file operations in the wrong location
- Efficiency: Mastering navigation shortcuts saves hours of typing
- Remote work: When SSH'd into a server, the GUI doesn't exist—navigation is everything
This tutorial teaches you the essential commands (pwd, cd, ls) and concepts (absolute vs relative paths, wildcards) that form the foundation of working with any Unix-like system.
The Linux Directory Structure
Linux follows the Filesystem Hierarchy Standard (FHS), a standard directory layout used by virtually all Unix-like systems. Understanding this structure helps you know where to find things and where to put things.
/ ← Root (the top-level directory—everything starts here)
├── bin/ ← Essential user binaries (ls, cp, mv, bash)
├── boot/ ← Boot loader files (kernel, initrd)
├── dev/ ← Device files (hard drives, USB, terminals)
├── etc/ ← System configuration files
├── home/ ← User home directories
│ ├── alice/ ← Alice's personal files
│ └── bob/ ← Bob's personal files
├── lib/ ← Shared libraries (like Windows DLLs)
├── media/ ← Mount points for removable media (USB drives, CDs)
├── mnt/ ← Mount points for temporary filesystems
├── opt/ ← Optional/third-party software
├── proc/ ← Virtual filesystem for process info (not real files!)
├── root/ ← Root user's home directory (not /home/root!)
├── sbin/ ← System administration binaries (requires root)
├── srv/ ← Service data (web servers, FTP)
├── sys/ ← Virtual filesystem for system/hardware info
├── tmp/ ← Temporary files (cleared on reboot)
├── usr/ ← User programs and data (read-only)
│ ├── bin/ ← User binaries (most commands you use)
│ ├── lib/ ← Libraries for /usr/bin programs
│ ├── local/ ← Locally installed software (not from packages)
│ └── share/ ← Shared data (docs, icons, man pages)
└── var/ ← Variable data (changes during operation)
├── log/ ← Log files (application and system logs)
├── tmp/ ← Temporary files (preserved across reboots)
└── www/ ← Web server files (on many systems)
Key Directory Purposes
| Directory | Purpose | Examples |
|---|---|---|
/bin | Essential commands needed in single-user mode | ls, cp, cat, bash |
/etc | System configuration files | nginx.conf, passwd, fstab |
/home | User home directories | /home/alice, /home/bob |
/tmp | Temporary files (anyone can write) | Session data, temp downloads |
/usr/bin | Most user commands | python, git, vim, wget |
/var/log | Log files | syslog, auth.log, nginx/access.log |
/opt | Third-party applications | /opt/google/chrome |
/dev | Device files | /dev/sda1 (hard drive), /dev/null |
ℹ️ Everything is a file
In Linux, virtually everything is represented as a file—regular files, directories, hardware devices (/dev/sda1), processes (/proc/1234), and even network connections. This "everything is a file" philosophy is one of Unix/Linux's most powerful design decisions, enabling uniform access patterns across different resources.
Why this matters: When you see a command like sudo nano /etc/nginx/nginx.conf, you immediately know:
/etc= system configurationnginx/= nginx-specific config- Requires
sudobecause system configs aren't user-writable
Absolute vs Relative Paths
Understanding paths is absolutely fundamental. Every file and directory has a path—the "address" of where it lives.
Absolute Paths
An absolute path always starts from the root directory (/) and specifies the complete location.
/home/alice/Documents/report.txt
/etc/nginx/nginx.conf
/var/log/syslog
/usr/bin/python3
Characteristics:
- Always starts with
/ - Works from anywhere (context-independent)
- Unambiguous—only one meaning
- Longer to type
When to use absolute paths:
- Scripts (so they work regardless of where you run them)
- Referring to system files (
/etc,/var/log) - When you need certainty about the exact location
Relative Paths
A relative path starts from your current directory and doesn't begin with /.
# If you're in /home/alice:
Documents/report.txt # Same as /home/alice/Documents/report.txt
../bob/file.txt # Go up to /home, then into bob/
../../etc/hostname # Go up twice to /, then into etc/
Characteristics:
- Does NOT start with
/ - Depends on current directory (context-dependent)
- Shorter to type
- Can break if you're not where you think you are
When to use relative paths:
- Interactive work (faster typing)
- Within a project directory structure
- Temporary navigation
Special Path Symbols
These special symbols save massive amounts of typing:
| Symbol | Meaning | Example | Result |
|---|---|---|---|
/ | Root directory | cd / | Go to root |
~ | Your home directory | cd ~/Documents | Go to your Documents folder |
. | Current directory | ./script.sh | Run script in current directory |
.. | Parent directory (one level up) | cd .. | Go up one level |
- | Previous directory | cd - | Toggle to last location |
~user | Another user's home | cd ~bob | Go to bob's home (if allowed) |
Example workflow:
pwd # /home/alice
cd /var/log # Absolute path to logs
pwd # /var/log
cd ~/Projects # ~ expands to /home/alice
pwd # /home/alice/Projects
cd .. # Go up one level
pwd # /home/alice
cd - # Go back to previous directory
pwd # /home/alice/Projects
💡 The tilde (~) is your friend
~ always expands to your home directory, no matter where you are. This makes commands portable:
cd ~always takes you homecp file.txt ~/backup/always copies to your backup folder~/.bashrcalways refers to your personal config
Much better than typing /home/alice every time!
pwd — Where Am I?
The pwd command (Print Working Directory) shows your current location in the filesystem. This is your "GPS coordinates" in the terminal.
pwd
# Output: /home/alice
# After navigating somewhere
cd /var/log
pwd
# Output: /var/log
# The environment variable $PWD also contains this info
echo $PWD
# Output: /var/log
Why you need pwd:
- Orientation: When you open a terminal, you might not know where you are
- Confirmation: Before running dangerous commands (
rm,mv), verify your location - Scripting: Capture the current directory to return to later
- Debugging: When commands fail, check if you're in the right place
# Common pattern: save location, do work elsewhere, return
original_dir=$(pwd)
cd /tmp
# ... do some work ...
cd "$original_dir" # Return to where you started
If you ever feel lost in the terminal, pwd is your GPS. Use it frequently when learning! Combine with ls to see what's around you: pwd; ls
cd — Moving Around
The cd command (Change Directory) is how you move through the filesystem. It's the most frequently used command you'll type.
Basic cd Usage
# Go to your home directory (all of these are equivalent)
cd
cd ~
cd $HOME
# Go to an absolute path
cd /var/log # System logs
cd /etc/nginx # Nginx configuration
cd /home/alice/Documents # Specific directory
# Go to a relative path (from current location)
cd Documents # Move into Documents subdirectory
cd Documents/Projects # Move into nested directory
cd Projects/my-app/src # Multiple levels at once
# Go up one level (to parent directory)
cd ..
# Go up two levels
cd ../..
# Go up and into a sibling directory
cd ../other-directory
# Go to the previous directory (toggle between two locations)
cd -
# Go to another user's home (if you have permission)
cd ~bob
Advanced cd Patterns
# Start in home directory
cd ~
pwd # /home/alice
# Navigate to a deeply nested project
cd Documents/Projects/web-app/frontend/src/components
pwd # /home/alice/Documents/Projects/web-app/frontend/src/components
# Quick jump to parent directory
cd ..
pwd # /home/alice/Documents/Projects/web-app/frontend/src
# Jump multiple levels up
cd ../../..
pwd # /home/alice/Documents/Projects
# Toggle between two directories (very useful!)
cd /var/log
pwd # /var/log
cd /etc/nginx
pwd # /etc/nginx
cd - # Back to /var/log
pwd # /var/log
cd - # Back to /etc/nginx
pwd # /etc/nginx
# Go to root, then home
cd /
pwd # /
cd
pwd # /home/alice
Tab Completion: Your Superpower
Tab completion is the single most important keyboard shortcut for navigation. It:
- Saves typing
- Prevents typos
- Shows you what's available
- Works with commands, files, directories, and variables
How it works:
- Type the first few letters of a directory name
- Press
Tab - If there's one match, it auto-completes
- If there are multiple matches, press
Tabtwice to see all options
# Example: navigating to /etc/nginx/
cd /etc/ng<Tab> # Completes to: cd /etc/nginx/
cd /etc/nginx/conf<Tab> # Completes to: cd /etc/nginx/conf.d/
# Multiple matches: press Tab twice to see options
cd /etc/n<Tab><Tab>
# Shows: netconfig network/ NetworkManager/ nginx/
# You can then type more characters and Tab again
cd /etc/ng<Tab> # Now completes uniquely to nginx/
💡 Use Tab completion religiously!
Never type full directory names manually. Always use Tab completion. It's faster, prevents errors, and shows you what exists. This habit alone will make you 10x faster in the terminal.
Common cd Mistakes and Solutions
Problem: cd to a directory with spaces
# Wrong (interprets as two arguments)
cd My Documents # Error: bash: cd: My: No such file or directory
# Right (quote the path)
cd "My Documents"
cd 'My Documents'
cd My\ Documents # Escape the space
Problem: Permission denied
cd /root # Error: Permission denied (unless you're root)
sudo cd /root # Still doesn't work (cd is a shell builtin)
# Solution: Use sudo -i or su to become root first
sudo -i # Become root
cd /root # Now works
ls — Listing Contents
The ls command (List) shows the contents of a directory. It's how you see what files and directories exist.
Basic ls Usage
# List files in current directory
ls
# List files in a specific directory
ls /etc
# List with details (long format)
ls -l
# List all files (including hidden files starting with .)
ls -a
# Combine options: long format + all files
ls -la
# Human-readable file sizes (KB, MB, GB)
ls -lh
Understanding ls -l Output
The long format (ls -l) shows detailed information about each file:
ls -l
Output:
-rw-r--r-- 1 alice staff 4096 Jan 15 10:30 document.txt
drwxr-xr-x 3 alice staff 4096 Jan 14 09:15 Projects
lrwxrwxrwx 1 alice staff 15 Jan 13 08:00 link -> /tmp/file
Let's decode each column:
-rw-r--r-- 1 alice staff 4096 Jan 15 10:30 document.txt
│├─┤├─┤├─┤ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ └─ Filename
│ │ │ │ │ │ │ │ └─ Last modified date/time
│ │ │ │ │ │ │ └─ Size in bytes
│ │ │ │ │ │ └─ Group owner
│ │ │ │ │ └─ User owner
│ │ │ │ └─ Number of hard links
│ │ │ └─ Others permissions (read, no write, no execute)
│ │ └─ Group permissions (read, no write, no execute)
│ └─ Owner permissions (read, write, no execute)
└─ File type
File Types (First Character)
| Character | Type | Example |
|---|---|---|
- | Regular file | -rw-r--r-- document.txt |
d | Directory | drwxr-xr-x Projects/ |
l | Symbolic link | lrwxrwxrwx link -> target |
c | Character device | crw-rw-rw- /dev/tty |
b | Block device | brw-rw---- /dev/sda1 |
p | Named pipe (FIFO) | prw-r--r-- pipe |
s | Socket | srwxrwxrwx socket |
Permission Characters
Permissions are shown as 9 characters in 3 groups of 3:
rwxr-xr-x
│││││││││
│││└┬┘└┬┘
│││ │ └─ Others: read + execute
│││ └─ Group: read + execute
│└┴─ Owner: read + write + execute
| Character | Meaning | For Files | For Directories |
|---|---|---|---|
r | Read | View file contents | List directory contents |
w | Write | Modify file | Create/delete files in directory |
x | Execute | Run as program | Enter directory (cd) |
- | No permission | Cannot perform action | Cannot perform action |
Essential ls Options
# Human-readable sizes (KB, MB, GB instead of bytes)
ls -lh
# Output: -rw-r--r-- 1 alice staff 4.0K Jan 15 10:30 document.txt
# Sort by modification time (newest first)
ls -lt
# Sort by modification time (oldest first)
ls -ltr
# Sort by size (largest first)
ls -lS
# Sort by size (smallest first)
ls -lSr
# Recursive (show contents of subdirectories)
ls -R
# Show only directories
ls -d */
# One file per line (useful for scripting)
ls -1
# Show file type indicators
ls -F
# / = directory, * = executable, @ = symlink, | = pipe
# All files, long format, human-readable, sorted by time
ls -alht
# List with full timestamps
ls -l --time-style=full-iso
# List inode numbers (useful for debugging hard links)
ls -li
# List with colors (usually aliased by default)
ls --color=auto
Practical ls Examples
# Find the largest files in a directory
ls -lhS /var/log | head -10
# Find recently modified files
ls -lt ~/Documents | head -10
# See hidden configuration files in your home directory
ls -la ~ | grep '^\.'
# Count files in a directory
ls -1 /etc | wc -l
# List only .txt files
ls -la *.txt
# List files matching a pattern
ls -la report_202*.pdf
# Show directory size summaries with du instead
ls -lh --block-size=M
du -sh */ # Better for directory sizes
# List files modified in the last 24 hours
ls -lt | grep "$(date '+%b %e')"
# List files by extension, sorted
ls -la | grep '\.txt$' | sort
Written by the ShellRAG Team
The ShellRAG editorial team writes practical, beginner-friendly Bash Shell tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.
Learn more about us →