Skip to content

Finding Your Way Around Linux ​

You're following a tutorial that tells you to edit a config file at /etc/nginx/nginx.conf, and you type the path and hit enter, and the file isn't there. Or maybe it is, but when you try to save your changes, the editor says the file is read-only. Or you're trying to figure out where Docker stores its images because your disk is full, and ls ~ isn't showing you anything that explains where 40 gigabytes went.

Knowing individual commands like cd and ls gets you around your home directory. Understanding the Linux filesystem — the tree structure, what lives where, who owns what, and how to find things you didn't put there yourself — is what turns the terminal from a narrow hallway into a building you can walk through with your eyes closed. AI development pulls in packages, caches models, writes logs, and spins up containers, all of which land in different parts of the tree. If you can't find them, you can't clean them up, and eventually you run out of disk space or permissions and don't know why.

What you'll learn

  • The Linux filesystem is a single tree rooted at / — everything, including external drives and network mounts, lives somewhere under that one root
  • Permissions (read, write, execute for owner, group, and others) control who can do what to every file and directory
  • find and locate are two different search strategies — one scans live, one queries an index — and you need both
  • du and df tell you where your disk space went, which is a question you'll ask every few weeks

The problem: you know the command but not where anything lives ​

On Windows, you have drive letters — C:, D:, and so on — and each one is its own root. Linux has one root, /, and everything hangs off it. A USB drive you plug in gets mounted somewhere like /media/usb. A network share appears at /mnt/nas. From the perspective of any program running on the system, it's all one tree.

Here are the directories you'll actually interact with:

DirectoryWhat's in itWhy you'll go there
/home/yournameYour personal files, projects, configsThis is your territory. Every project, every config file, every downloaded model lives here or under here
/etcSystem-wide configuration filesEditing /etc/hosts for local DNS, /etc/nginx/ for web server config, /etc/systemd/ for service definitions
/varVariable data: logs, databases, caches/var/log/ is where system and service logs live. /var/lib/docker/ is where Docker stores images and containers — often the culprit when disk space vanishes
/tmpTemporary files, cleared on rebootScratch space. Good for one-off file operations you don't care about keeping
/usrInstalled software, libraries, shared resources/usr/bin/ is where most commands live. Python packages installed globally go under /usr/lib/python3/
/optOptional, manually installed softwareSome third-party tools install here. If you install something from a tarball rather than a package manager, it might land in /opt

The mental model to carry around: /home is yours, /etc is configuration you didn't write but sometimes need to edit, /var is data the system generates (and where runaway logs eat your disk), and everything else is the operating system doing its job.

Absolute vs. relative paths ​

An absolute path starts with / and describes the full route from the root of the tree: /home/yourname/projects/agent/main.py. No matter what directory you're currently in, that path always points to the same file.

A relative path starts from where you are right now. If you're in /home/yourname/projects, then agent/main.py and ./agent/main.py both resolve to the same absolute path as above. The dot means "this directory." Two dots means "up one level": from /home/yourname/projects, ../.. takes you to /home.

When to use which: absolute paths in scripts and config files (they don't break when the script is run from a different directory). Relative paths at the interactive prompt (less typing, and tab completion fills them in).

Options & when to use each ​

Here is how the different approaches for navigating and managing the Linux filesystem compare.

ApproachGood forCosts youWhen to pick it
Terminal (cd, ls, find)Speed, scripting, remote servers, bulk operationsSteeper learning curve — you need to know the commandsAny time you are doing more than a one-off drag-and-drop
GUI file managerCasual browsing, previewing images, drag-and-drop movesCannot be scripted or chained with other toolsQuick visual tasks where you do not need to automate
findSearching by name, size, modification time, permissions — live scan of the actual filesystemSlower on large directory trees because it reads the disk every timeOne-off searches, or when you need filters locate does not support
locateBlazing fast name-only search using a pre-built indexOnly searches by filename, index only updates once a dayRepeated searches for files you know the name of
du+dfFinding disk hogs — what is eating your storageTerminal-only, no pretty charts"Why is my disk full?" — this is the answer

Permissions: who can do what ​

Every file and directory has an owner, a group, and a set of permissions for three categories of users: the owner, members of the group, and everyone else. Each category gets three permissions: read (r), write (w), and execute (x).

bash
$ ls -la
drwxr-xr-x  2 alice devs  4096 Aug  1 10:00 src/
-rw-r--r--  1 alice devs  1240 Aug  1 09:45 main.py
-rwxr-xr-x  1 alice devs   312 Aug  1 09:45 deploy.sh

Let's decode the first line: drwxr-xr-x. The d means it's a directory. Then three triplets:

  • rwx — owner (alice) can read, write, and execute (for a directory, "execute" means "can cd into it")
  • r-x — group (devs) can read and execute, but not write
  • r-x — everyone else can read and execute, but not write

For main.py: -rw-r--r--. The - means it's a regular file (not a directory). Owner can read and write. Group and others can only read. Nobody can execute it — and that's correct for a Python file you run with python main.py, because the executable is python, not main.py itself.

For deploy.sh: -rwxr-xr-x. Owner can read, write, and execute. Everyone else can read and execute. This is a shell script you want to be able to run directly with ./deploy.sh.

Changing permissions ​

bash
# Make a script executable by its owner
chmod u+x deploy.sh

# Remove write permission from group and others
chmod go-w config.yaml

# Set permissions numerically: owner=rwx, group=rx, others=nothing
chmod 750 private_script.sh

The numeric mode maps each permission to a bit: read=4, write=2, execute=1. Add them up for each category. 750 means: owner gets 4+2+1=7 (rwx), group gets 4+1=5 (r-x), others get 0 (nothing).

Numeric mode is for setting all permissions at once. Symbolic mode (u+x, go-w) is for adjusting one category without touching the others. Use symbolic when you're adding or removing a single permission. Use numeric in scripts, where you want to be explicit about the exact final state.

Changing ownership ​

bash
# Change owner
sudo chown bob important_file.txt

# Change owner and group
sudo chown bob:devs important_file.txt

# Change recursively (entire directory tree)
sudo chown -R bob:devs ~/projects/shared_agent/

You almost never need chown for files in your home directory — you already own everything you create there. chown is for files you've inherited from other users, or system files you've copied, or directories you want to share with someone else on the same machine.

Finding things: find vs. locate ​

These two commands solve the same problem — "where is that file?" — with completely different mechanics.

findlocate
How it worksWalks the filesystem tree live, testing every file against your criteriaQueries a pre-built database that's updated once a day by updatedb
SpeedSlow on large directory treesNearly instant
FreshnessAlways current — sees files created one second agoUp to 24 hours stale — won't see files created since the last updatedb run
PowerCan filter by name, type, size, modification time, permissions, and execute commands on matchesSimple substring match on file paths
When to useSearching a specific project directory, or when you need complex filters"I know the filename contains 'cublas' and I have no idea where it is"

find by example ​

bash
# All Python files modified in the last day
find ~/projects -name "*.py" -mtime -1

# Directories only, no files
find . -type d -name "logs"

# Files larger than 100MB (great for finding disk hogs)
find / -type f -size +100M 2>/dev/null

# Find and delete all .pyc files
find . -name "*.pyc" -delete

The 2>/dev/null on that third example is important: running find on / will hit directories you don't have permission to read, and without it your terminal fills with "Permission denied" noise. The 2>/dev/null sends all those errors to the void so you only see the actual results.

locate by example ​

bash
# Find anything with "cuda" in the path
locate cuda

# Case-insensitive
locate -i Dockerfile

# Count matches
locate -c "*.so"

# If locate says "database not found," build it first
sudo updatedb

locate is what you use when you know the name but not the location. A model weights file called pytorch_model.bin that you downloaded weeks ago? locate pytorch_model.bin finds it in under a second. find / -name "pytorch_model.bin" would take minutes.

Disk space: where did it all go? ​

Two commands answer the two disk questions you'll have.

df -h tells you how much space is free on each mounted filesystem. The -h flag makes the output human-readable (G for gigabytes instead of raw blocks).

bash
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  200G  140G   50G  74% /

When your download fails with "no space left on device," df -h confirms it and shows you which filesystem is full.

du tells you how much space a directory and its contents are using. It's how you find the culprit.

bash
# How much space is my home directory using?
du -sh ~

# What are the 10 largest directories in my home?
du -h ~ | sort -hr | head -10

# What's eating space in /var?
sudo du -sh /var/* | sort -hr | head -10

That last one is the debugging sequence for "my disk is full and I don't know why." Run it on /var first (Docker and logs love to hide there), then on ~ (model caches and Python environments), then on /tmp if you're still looking. The answer is almost always Docker images you forgot to prune, Python packages cached from old environments, or a log file that grew to 30GB because a process has been repeating the same error every millisecond for three weeks.

Build it: navigate, permission, find, and measure ​

Let's work through a realistic session that ties these tools together. You've just cloned an agent project and you want to understand its layout, fix a permission issue, and check that you have enough disk space.

Step 1: Get your bearings.

bash
cd ~/projects/customer-support-agent
pwd
ls -la

Look at the directory structure. Which entries are directories, which are files? Who owns them? Are there any .env or .gitignore files that are hidden by default?

Step 2: Find every Python file and count them.

bash
find . -name "*.py" | wc -l

This tells you the scale of the project. A dozen Python files is a script. A thousand is a framework.

Step 3: Check if there's a config file you can't edit.

bash
ls -la config/

If you see -r--r--r-- on a file you need to edit, you own it but can only read it. Fix it:

bash
chmod u+w config/settings.yaml

If you see a user other than your own name as the owner, you'll need sudo chown instead.

Step 4: Find the largest files in the project.

bash
find . -type f -size +10M -exec ls -lh {} \;

Model weights, datasets, cached embeddings — AI projects accumulate large files. Knowing which ones exist and where they are saves you from surprise disk-full errors.

Step 5: Check overall disk health.

bash
df -h ~
du -sh ~/.cache/
du -sh ~/projects/

If ~/.cache/ is 30GB, that's likely Hugging Face model downloads and pip caches. You can clean it with uv cache clean and pip cache purge when you need the space back.

What goes wrong ​

MistakeHow you notice itThe fix
chmod 777 on everythingYou got a permission error, googled it, and applied the nuclear option: chmod -R 777 .777 means anyone on the system can read, write, and execute your files. For scripts, chmod u+x is almost always sufficient. For config files, chmod 600 keeps them private to you
rm -rf /tmp/* thinking it's safe/tmp is supposed to be temporary, right? But a running database or web server might have its socket file there/tmp is fair game on a fresh system, but on a running development machine, check what's in there first with ls /tmp. Processes depend on files that happen to live in /tmp
find with no path argumentfind -name "*.py" works on some systems and fails on others — find expects a path as the first argumentAlways include the starting path: find . -name "*.py". It's explicit, it's portable, and it prevents confusion
Confusing du and dfdf -h says the disk is 90% full, but du -sh / only reports 60GB on a 200GB drivedf measures filesystem-level allocation. If a file has been deleted but a process still has it open, the space isn't freed until that process closes it. Check with lsof | grep deleted to find these ghost files
locate returns nothing for a file you know existsYou created the file five minutes ago, but locate queries yesterday's indexRun sudo updatedb to rebuild the index, or use find for freshly created files

Confirm it worked ​

Open a terminal and work through these:

  • Run ls -la / and identify at least five of the top-level directories by what they contain
  • Navigate to a project directory, find all .py files modified in the last 7 days: find . -name "*.py" -mtime -7
  • Create a test file: echo "test" > /tmp/test_perms, then chmod 000 /tmp/test_perms, try to cat it, observe the permission error, then chmod 644 /tmp/test_perms and try again
  • Run du -sh /var/lib/docker 2>/dev/null to see how much space Docker is using (it might be zero if you don't have Docker installed — that's fine)
  • Use locate bashrc (run sudo updatedb first if needed) to find every bashrc file on the system

If you can navigate to any directory on the system, read its permissions, and explain why you can or can't write to it, you've got this.

Next: Shell & Workspace Performance — aliases, lazy-loading, tmux, and making your terminal faster.