2. Navigating the file system
What you will learn in this chapter:
pwd/ls/cd— where am I, what's here, where do I go?mkdir/touch— creating directories and filescp/mv/rm— copying, moving, deleting- The difference between absolute and relative paths (
/etc/hostsvs../config)- Hidden files (those starting with
.) and glob patterns⏱ Time: ~25 minutes 🧪 Exercises:
bashlings watch— 8 interactive exercises ready (exercises/02_navigation/)
The Linux/Unix file system is one big tree. Its root is represented by the / symbol. Everything lives under this root: user files, programs, devices, and even system settings.
/
├── bin/ # core executable files (ls, cat, ...)
├── etc/ # configuration files
├── home/ # user directory (Linux)
├── Users/ # user directory (macOS)
├── tmp/ # temporary files
├── usr/ # additional programs and libraries
└── var/ # logs, mail, and variable data2
3
4
5
6
7
8
2.1. pwd — where am I?
pwd (Print Working Directory) — shows the full path of the directory you are currently in.
$ pwd
/Users/mac/Desktop/projects2
Absolute and Relative paths
- Absolute path — starts from
/:/Users/mac/Documents - Relative path — relative to the current directory:
./docsor../images
2.2. ls — files in a directory
ls (list) — lists the files in the current or a specified directory.
ls # simple listing
ls -l # detailed (long format)
ls -a # including hidden files (.)
ls -lh # human-readable size (KB, MB)
ls -la # the most commonly used combination
ls -lt # ordered by time
ls -lS # ordered by size
ls /etc # contents of another directory
ls *.md # only .md files2
3
4
5
6
7
8
9
Output of ls -l:
-rw-r--r-- 1 mac staff 2.1K Mar 14 10:22 README.md
drwxr-xr-x 4 mac staff 128B Mar 12 09:00 src2
Each column:
| Column | Meaning |
|---|---|
-rw-r--r-- | Permissions |
1 | Number of hard links |
mac | Owner |
staff | Group |
2.1K | Size |
Mar 14 10:22 | Modification time |
README.md | File name |
Permission symbols
-— regular file,d— directory,l— symlinkr— read,w— write,x— execute- Order: owner / group / others
2.3. cd — change directory
cd (Change Directory):
cd /etc # by absolute path
cd Documents # to Documents inside the current directory
cd .. # one level up
cd ../.. # two levels up
cd ~ # to the home directory
cd # also to the home directory (shortcut)
cd - # back to the previous directory
cd / # to the root2
3
4
5
6
7
8
Shortcuts
| Symbol | Meaning |
|---|---|
~ | Home directory (/Users/mac) |
. | Current directory |
.. | Parent directory |
- | Previous directory (with cd -) |
2.4. mkdir — create a new directory
mkdir loyiha # a single directory
mkdir loyiha tests docs # multiple directories
mkdir -p src/components/buttons # nested (parents are created too)
mkdir -v new_folder # verbose: shows what was done2
3
4
The -p (parent) flag is very powerful — if directories in the path don't exist, it creates them all:
mkdir -p projects/2026/january/reports
# all 4 levels are created2
mkdir errors
Without -p, if a parent directory does not exist, it raises an error:
mkdir: a/b/c: No such file or directory2.5. touch — create an empty file
touch readme.txt # a new empty file
touch file1.txt file2.txt # multiple files
touch -t 202601011200 old.txt # create with a set timestamp2
3
An extra job of touch
If the file already exists, touch updates its last modification time (not its contents).
2.6. cp — copy
cp manba.txt nusxa.txt # copy of a file
cp file.txt /tmp/ # to another directory
cp -r src/ backup/ # recursive (for directories)
cp -v a.txt b.txt # verbose
cp -i a.txt b.txt # interactive (asks before overwriting)
cp -p file.txt copy.txt # preserve permissions and timestamp
cp *.md docs/ # all .md files2
3
4
5
6
7
-r is required
If you want to copy a directory, don't forget the -r (recursive) flag:
cp folder1 folder2 # WRONG
cp -r folder1 folder2 # CORRECT2
2.7. mv — move or rename
mv does two jobs: moving files to another location and renaming.
mv eski.txt yangi.txt # rename
mv file.txt /tmp/ # move
mv *.log logs/ # multiple files
mv -i a.txt b.txt # interactive
mv -n a.txt b.txt # don't overwrite if it exists
mv -v old.txt new.txt # verbose2
3
4
5
6
Trick
mv doesn't require -r for directories — it always works "fully":
mv src/ archive/ # works correctly2.8. rm — delete
The most dangerous command!
A file deleted with rm cannot be recovered. It doesn't go to the Trash. It's gone — that's it.
rm fayl.txt # a single file
rm a.txt b.txt c.txt # multiple files
rm -i fayl.txt # asks for confirmation
rm -f fayl.txt # force, without asking
rm -r katalog/ # recursive (for directories)
rm -rf katalog/ # FORCE + RECURSIVE — be careful!2
3
4
5
6
Dangerous antipatterns
rm -rf / # ❌ deletes the entire system
rm -rf $UNDEFINED_VAR/* # ❌ if the variable is empty = rm -rf /
rm -rf * .git # ⚠ watch out for the space2
3
Safe practice
- Instead of
rm, use safe-delete utilities liketrashorgomi. - Before ever using
rm -rfwith a variable, check it withecho:
echo rm -rf "$PROJECT_DIR" # first we look
rm -rf "$PROJECT_DIR" # now we run it2
2.9. rmdir — remove an empty directory
rmdir only removes empty directories:
rmdir empty_folder # removes it if empty
rmdir non_empty # ERROR: "Directory not empty"2
For a non-empty directory, use rm -r.
2.10. tree — tree view
Displays the directory structure visually (you may need to install it separately):
brew install tree # macOS
sudo apt install tree # Ubuntu/Debian
tree # current directory
tree -L 2 # up to 2 levels
tree -a # including hidden files
tree -d # only directories2
3
4
5
6
7
Output:
.
├── docs/
│ ├── part1/
│ │ ├── 01-introduction.md
│ │ └── 02-navigation.md
│ └── index.md
└── package.json2
3
4
5
6
7
2.11. Wildcards (Globbing)
Bash supports wildcard (joker) symbols for specifying multiple files:
| Symbol | Meaning | Example |
|---|---|---|
* | Any character(s) | *.txt, report-* |
? | Exactly one character | file?.txt |
[abc] | One of a, b, or c | f[123].log |
[a-z] | A range | [a-c]*.md |
{a,b} | Brace expansion | {src,test}/*.js |
Examples:
ls *.md # all .md files
rm temp_?.log # temp_1.log, temp_2.log, ...
cp report-{2024,2025}.pdf bk/ # works with both
ls /etc/[a-c]* # those starting with a, b, or c2
3
4
2.12. Real example: creating a project skeleton
# 1. Main directory
mkdir -p ~/projects/my-app
cd ~/projects/my-app
# 2. Structure
mkdir -p src/{components,utils,services} tests docs
# 3. Empty files
touch README.md .gitignore package.json
touch src/index.js src/utils/helpers.js
# 4. Let's check
tree -L 32
3
4
5
6
7
8
9
10
11
12
13
2.13. Exercises
🧪 Bashlings — interactive exercises
This chapter's 8 exercises come with auto-checking via the bashlings CLI:
bashlings watch # start from the first pending exercise
bashlings run nav1 # check a single exercise
bashlings hint nav1 # step-by-step hint2
3
Source: exercises/02_navigation/
Do the following additional tasks by hand in the terminal:
- In your home directory, create a directory named
bash-mashqand, inside it, create the subdirectoriesnotes,scripts, andarchivewith a single command. - Inside
scripts/, create the fileshello.sh,backup.sh, andcleanup.sh. - Make a copy of
hello.shnamedhello.bakin the same directory. - Delete the
archivedirectory. - Move all
.shfiles into thenotes/directory with a single command.
2.14. Summary
| Command | Purpose |
|---|---|
pwd | Show the current directory |
ls | View the contents of a directory |
cd | Change directory |
mkdir | Create a new directory |
touch | Create a new empty file |
cp | Copy |
mv | Move or rename |
rm | Delete (with care!) |
rmdir | Remove an empty directory |
tree | Display in a tree view |
Now you have the skill to move freely around the file system. In the next chapter we will learn to connect commands through I/O redirection and pipelines.
Next page: 3. I/O Redirection and Pipelines →