Mastering Linux navigation and file management commands: pwd, ls, cd, mkdir, touch, cp, mv, rm, and rmdir, plus wildcards for file patterns, complete with exercises to build a real project structure.

After episode 2 where we dissected the Linux system architecture and the Filesystem Hierarchy Standard — understanding that /etc is for configuration, /var for variable data, and /home for personal files — in this episode we'll put that map to practical use: navigating the filesystem and managing files/folders. These are skills you'll use every day, in every episode of this series, and in every real Linux administration job.
Think of the Linux filesystem as a large house with many rooms. Episode 2 gave you the house plan (the FHS); this episode 3 teaches you how to walk around inside it — opening room doors, moving furniture, copying, and rearranging. Without this ability, you'll keep getting lost, and every DevOps tool (Docker, systemd, SSH) that manipulates files will feel like a mystery.
In this episode we'll cover navigation commands (pwd, ls, cd), directory management (mkdir, rmdir), file creation (touch), copying (cp), moving (mv), deletion (rm), and wildcards that let you manipulate many files at once — closing with an exercise to build a real project structure and a list of common pitfalls.
pwd and the Shell PromptBefore walking, you need to know where you are. The pwd command (Print Working Directory) shows the directory you're currently in:
pwd
/home/armanAlso pay attention to the shell prompt — the text before the cursor in the terminal. The prompt usually shows user@host:path$. The path part indicates the current directory; the ~ sign means /home/<user>. So the prompt arman@learn-linux:~$ means you're in /home/arman. Getting used to reading the prompt will prevent you from getting "lost" in the filesystem.
ls: Reading Directory ContentsThe ls (list) command shows directory contents. It's the most used command in Linux, and its options heavily determine the quality of the output:
ls # list ordinary files
ls -l # long format: permission, owner, size, date, name
ls -a # show all files including hidden (.config)
ls -h # file size in human-readable format (K, M, G)
ls -la # combination: all files, long format, human-readable sizeLet's break down the ls -l output line by line:
-rw-r--r-- 1 arman arman 1234 Jul 10 09:30 report.txt| Column | Meaning |
|---|---|
-rw-r--r-- | File type (-=file, d=directory) + user/group/others permissions |
1 | Number of hard links |
arman | File owner |
arman | Owner group |
1234 | File size (bytes) |
Jul 10 09:30 | Last modification date |
report.txt | File name |
The -t option sorts by time (newest first) and -S by size (largest first) — very useful for finding recently modified files or files hogging disk:
ls -lt
ls -lSTip
A professional habit: use ls -la by default. From it you can immediately see permissions, owner, size, and hidden files. Don't memorize every ls option — use man ls or ls --help whenever you need to; the options -h, -a, -l, -t, -S already cover 90% of daily needs.
cd: Changing Directoriescd (change directory) moves you between directories. The four most used targets:
| Syntax | Destination |
|---|---|
cd /etc | Move to an absolute path (starting from /) |
cd docs | Move to a relative subdirectory (relative to the current position) |
cd .. | Go up one level to the parent directory |
cd ~ | Move to the user's home directory |
cd - | Return to the previous directory (very useful for jumping around) |
cd /etc
pwd # /etc
cd ..
pwd # /
cd /home/arman
cd -
pwd # / (returned to the previous directory)Notice two important concepts: absolute paths (always starting with /) vs relative paths (relative to the current position). As a rule of thumb, use absolute paths in scripts so they don't depend on location; interactively, relative paths are faster.
The dot characters also matter: . means "current directory" and .. means "parent directory". Both are hidden entries present in every directory.
mkdir & rmdirTo create a new directory use mkdir (make directory). The -p option creates nested directories at once and doesn't error if they already exist:
mkdir -p project/src/lib
mkdir -p project/docsWithout -p, mkdir project/src/lib will fail if project doesn't exist yet. With -p, the whole chain of directories is created automatically — one of the commands that most often saves you from "No such file or directory" errors.
To remove an empty directory use rmdir. Remember: rmdir only removes empty directories; if it contains files, it refuses. For directories with contents, we'll use rm -r (covered shortly).
touchtouch has two functions: creating a new empty file, and updating the timestamp of an existing file:
touch README.md
touch report.txt
ls -laThe main use of touch in real workflows: creating placeholder files (for example, testing a writable path), or forcing processes triggered by file changes (like systemd path units or tooling such as make) to see a file as "newly modified".
cpcp (copy) copies files or directories. The golden rule most beginners forget: copying folders REQUIRES -r (recursive).
cp report.txt backup/ # copy a file to another directory
cp report.txt backup/backup.txt # copy with a new name
cp -r project/ project-backup/ # copy a folder with full contents (-r!)
cp -i report.txt backup/ # -i: confirm before overwritingcp -r copies the entire contents of a directory recursively. Without -r, copying a folder will fail with the error omitting directory.cp -i (interactive) asks for confirmation before overwriting an existing file — a powerful safeguard against data loss from accidental overwrites.Warning
cp silently overwrites the destination file without confirmation. Imagine running cp config.yaml config.yaml.bak but there's already an important config.yaml.bak — its contents are gone instantly. Make a habit of using -i for commands that write to existing files, and always think about the destination before executing.
mvmv (move) does two things: moving files/folders to another location, and renaming. It works without copying data — it only updates position metadata, so it's very fast even for large files:
mv report.txt documents/ # move to another folder
mv report.txt documents/report.txt # combine move + rename
mv config.yaml config.old # rename in the same directory
mv project/ /home/arman/backup/ # move a folder (no -r needed)Note: unlike cp, mv for folders doesn't need -r — moving a folder is a safe operation because it doesn't copy contents. It's a small difference that often confuses people.
rm and rm -rfrm (remove) deletes files. For directories with contents, you need -r (recursive); to delete without asking, you need -f (force). The combination — rm -rf — is one of the most dangerous commands in Linux.
rm report.txt # delete one file
rm -i report.txt # confirm before deleting
rm -r project/ # delete a folder and its contents
rm -f report.txt # force: no confirmation, ignore errors
rm -rf project/ # ⚠️ delete folder + contents without confirmationBecause rm -rf deletes without confirmation and without a trash bin, a single typo in the path can wipe valuable data. Watch out for these two classic disasters:
rm -rf ~ /etc # ⚠️ line 1: extra space — deletes home & /etc!
rm -rf /var/l/og # ⚠️ line 2: typo in log pathCaution
There is no undo for rm in Linux. Unlike Windows with its Recycle Bin, files deleted with rm can't be recovered (except through expensive, unreliable forensic recovery). Safety rules: (1) always type the full path carefully, (2) check with ls first before deleting, (3) use -i when in doubt, and (4) in critical directories like /etc, avoid rm for files you haven't backed up. When in doubt: stop, check, then execute.
*, ?, and []Now the part that makes Linux feel powerful: wildcards (globbing). Wildcards are patterns for matching many file names at once — the shell expands them before the command is executed.
| Wildcard | Meaning | Example | Matches |
|---|---|---|---|
* | Zero or more of any character | *.log | error.log, access.log, a.log |
? | Exactly one character | report?.txt | report1.txt, reportA.txt |
[] | One character from the list | file[12].txt | file1.txt, file2.txt |
ls *.log # all log files
rm -i report?.txt # delete report + 1 character, with confirmation
ls report[12].txt # only report1.txt and report2.txt
cp *.conf /etc-backup/ # copy all config files at onceWhy are wildcards so important? Because Linux administration almost always deals with many files at once — cleaning up old logs, moving file batches, or copying all configurations. Imagine having to type rm a hundred times for a hundred files; with rm *.tmp it's just one line.
Note
Wildcards are expanded by the shell, not by the program. When you type ls *.log, the shell matches the pattern into a list of files, then passes that list to ls. This explains why a pattern matching nothing (for example ls *.xyz when there are no .xyz files) gets sent as-is as a literal file name — so ls reports No such file or directory: *.xyz. Regular typing habits at the terminal will make this feel natural.
Now let's combine all the commands into one exercise that mirrors day-to-day work. We'll build a project structure for a web application with frontend and backend parts:
cd ~
mkdir -p myapp/src/components
mkdir -p myapp/src/utils
mkdir -p myapp/tests/fixtures
mkdir -p myapp/docs
touch myapp/README.md
touch myapp/src/components/Button.tsx
touch myapp/src/utils/format.ts
cp myapp/README.md myapp/docs/README.md
ls -R myappmyapp:
README.md docs src tests
myapp/docs:
README.md
myapp/src:
components utils
myapp/src/components:
Button.tsx
myapp/src/utils:
format.ts
myapp/tests:
fixturesNotice the efficient flow: create all directories at once with mkdir -p (one line, not six), then create files with touch, copy a file with cp, and verify with ls -R (recursive — shows the entire tree). This exercise is the basic pattern you'll repeat hundreds of times in the real world.
| Mistake | Symptom | Solution |
|---|---|---|
rm -rf on the wrong path | Important data lost permanently | Type paths carefully, ls first, use -i |
cp a folder without -r | cp: -r not specified; omitting directory | Always cp -r for directories |
| Spaces in file names without escaping | File "splits" into two arguments | Use \ (escape), quotes "my file.txt", or Tab autocomplete |
cd .. too many times | In an unwanted directory | Use pwd and cd - to get back |
rmdir on a non-empty directory | rmdir: failed to remove 'x': Directory not empty | Use rm -r (or check contents first with ls) |
| Deleting a file still in use | Process errors when it needs the file | lsof <file> to check processes using it |
About spaces in file names: don't be afraid, but always handle them properly. The safest way is to type with Tab autocomplete — the shell escapes spaces automatically. Manually: cd "My Documents" or cd My\ Documents.
In this episode 3, you've mastered navigation and file management commands: pwd and ls for orientation, cd for moving around, mkdir/rmdir for managing directories, touch for creating files, cp for copying, mv for moving/renaming, rm for deleting, and the wildcards *, ?, [] for manipulating many files at once — all combined in an exercise to build a real project structure.
Key takeaways:
pwd and ls — know where you are and what's there.cp -r for folders, mv without -r — a difference that saves you from errors and confusion.rm -rf is very dangerous — there's no undo in Linux; always check the path before executing.\ escape or quotes.Now you can "walk" inside the Linux filesystem. In the next episode 4, we'll cover an equally important skill: Reading, Viewing & Editing Text Files — mastering cat, less, head, tail -f for reading files and monitoring logs in real time, plus the nano and vim editors for editing configuration files. Stay motivated, because the more tools you master, the "wilder" your productivity in the terminal becomes!