---
id: 2025-05-14-lpic-1-basic-navigation-and-filesystem-commands
slug: lpic-1-basic-navigation-and-filesystem-commands
title: "LPIC-1: basic navigation and filesystem commands"
excerpt: "Core Linux file-management commands: FHS layout, wildcards and symbolic links — required knowledge for the LPIC-1 exam."
date: "2025-05-14T09:00:00+02:00"
updated: "2025-05-15T09:00:00+02:00"
author:
  name: "Sebastian Palencsár"
  handle: "spalencsar"
category: "lpic-1-serie"
tags: ["lpic-1", "lpic-1-serie", "bash", "linuxadmin", "linuxtutorial", "shell", "filesystem"]
reading_time: 52
toc: true
---

Filesystem navigation and the basic file-management commands are daily Linux admin work. They sit on the [Linux command-line concepts](/en/lpic-1-serie/lpic-1-understanding-the-linux-command-line-shell-terminal-and-first-commands){.badge-link-text} from the first LPIC-1 module.

If you cannot use the filesystem efficiently, even simple tasks stall. That is why this topic takes a large share of LPIC-1 exam 101 and is among the most frequently asked areas.

<blockquote class="infobox infobox--practice">
❗ **Important note:** As with the first module, this is not an official exam-prep course for the [LPIC-1 certification](https://www.lpi.org/our-certifications/lpic-1-overview/){.badge-link-text}. It is a practice-oriented companion for self-study, so you can understand and apply the denser topics more reliably.
</blockquote>

### What this module covers

The following sections cover:

* The standardised structure of the Linux filesystem
* Efficient navigation with the core commands (`pwd`, `ls`, `cd`)
* The difference between absolute and relative paths
* Wildcards for working on several files at once
* Creating, copying, moving and deleting files and directories
* Differences between symbolic links and hard links

**Especially useful for LPIC-1 candidates:** typical exam questions and pitfalls, so you go in prepared.

### Who this module is for

**This module is for:**

* Aspiring Linux administrators preparing for LPIC-1
* Linux beginners who want to build command-line skills systematically
* IT professionals from other fields who want to refresh Linux
* Anyone who wants practical, clearly explained examples

## Understanding the Linux directory structure

One of the first hurdles for Linux beginners is orientation in the filesystem. Unlike Windows there are no drive letters such as `C:` or `D:`. Linux has a single, connected directory tree organised to a standard.

### The Filesystem Hierarchy Standard (FHS)

The [Filesystem Hierarchy Standard](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard){.badge-link-text} (FHS) is a Linux Foundation guideline for the directory layout of Unix-like operating systems. It started in 1993 and is currently at version 3.0.

The FHS defines where given file types and programs should live in the filesystem:

```markdown
┌─ Filesystem Hierarchy Standard (FHS) ───────────────────────┐
│ /                                                           │
│ ├── bin/    → Essential system commands (sh, bash, ls, cp)  │
│ ├── boot/   → Kernel, initial RAM disk (initramfs) & GRUB   │
│ ├── dev/    → Device files (sda, nvme0n1, tty, null, urand) │
│ ├── etc/    → System-wide config files (passwd)             │
│ ├── home/   → Personal user home directories                │
│ ├── lib/    → Shared libraries & kernel modules             │
│ ├── media/  → Mount points for removable media (USB, CD)    │
│ ├── mnt/    → Temporary mount points for filesystems        │
│ ├── opt/    → Additional third-party software packages      │
│ ├── proc/   → Virtual filesystem for process & kernel       │
│ ├── root/   → Home directory of the superuser (root)        │
│ ├── sbin/   → Essential admin system commands               │
│ ├── sys/    → Virtual filesystem for hardware & drivers     │
│ ├── tmp/    → Temporary files (often cleared on reboot)     │
│ ├── usr/    → Secondary hierarchy for user programs         │
│ └── var/    → Variable data (logs, spools, caches, DBs)     │
└─────────────────────────────────────────────────────────────┘
```

<blockquote class="infobox infobox--info">
💡 **Tip:** The FHS keeps Linux distributions broadly similar. As an administrator you can find your way on different systems because configuration files live in `/etc` and user homes in `/home`.
</blockquote>

<span class="nb-accent">Important system directories and their roles</span>

A structured overview of the central Linux filesystem directories:

| Directory | Name | Role and typical contents |
|---|---|---|
| `/` | Root directory (*root*) | The top of the filesystem and the starting point of every absolute path. |
| `/bin` | *Binaries* | Essential system commands (`ls`, `cp`, `mv`, `chmod`) available to all users. |
| `/boot` | *Bootloader* | Files needed to start the system (kernel images, initramfs, GRUB configuration). |
| `/dev` | *Devices* | Device files for physical hardware (e.g. `sda`, `nvme0n1`) and virtual devices (`null`, `urandom`). |
| `/etc` | *Configuration* | Central configuration for services, system management, networking and accounts. |
| `/home` | *User homes* | Home directories of regular users (e.g. `/home/username`). |
| `/lib`, `/lib64` | *Libraries* | Essential system libraries and kernel modules for programs in `/bin` and `/sbin`. |
| `/media` | *Removable media* | Automatic mount points for removable media (USB sticks, external disks, DVDs). |
| `/mnt` | *Mount* | Temporary mount points for filesystems the administrator mounts by hand. |
| `/opt` | *Optional software* | Extra, self-contained third-party software packages. |
| `/proc` | *Processes (virtual)* | Virtual RAM filesystem for process and kernel information. |
| `/root` | *Superuser home* | Home directory of the administrator (*root*), kept apart from `/home` for security. |
| `/sbin` | *System binaries* | Essential system and admin commands (`fdisk`, `reboot`, `iptables`). |
| `/sys` | *System (virtual)* | Virtual filesystem for hardware drivers and kernel device state. |
| `/tmp` | *Temporary* | Temporary space for all programs, usually cleared on reboot. |
| `/usr` | *Unix System Resources* | Secondary hierarchy for installed user software, documentation and headers (`/usr/bin`, `/usr/share`). |
| `/var` | *Variable data* | Changing data such as logs (`/var/log`), spools, caches and databases. |

🔧 **Practical example: inspect configuration files in `/etc`**

```bash
ls -l /etc/
total 1088
-rw-r--r-- 1 root root 3028 Jan  3  2024 adduser.conf
drwxr-xr-x 2 root root 4096 Mar 25  2024 apt
-rw-r--r-- 1 root root 2319 Apr  4  2023 bash.bashrc
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** As a beginner, do not change anything in `/`, `/bin`, `/sbin`, `/lib` and `/etc` unless you know exactly what you are doing. Small mistakes here can make the system unusable.
</blockquote>

<span class="nb-accent">How FHS categorises files</span>

FHS splits files along two dimensions:

| Dimension | Category | Description and examples |
|---|---|---|
| **Changeability** | **Static** | Files that do not change without an explicit admin action (e.g. binaries in `/bin`, libraries in `/lib`, documentation in `/usr/share/man`). |
| | **Variable** | Files that change while the system runs (e.g. logs in `/var/log`, mail spools in `/var/spool/mail`, temporary data in `/tmp`). |
| **Shareability** | **Shareable** | Files that can be shared with other machines over the network (e.g. application software in `/usr`, optional packages in `/opt`). |
| | **Unshareable** | Machine-specific data that must stay local (e.g. configuration in `/etc`, boot files in `/boot`, lock files in `/var/lock`). |

<span class="nb-accent">Differences between distributions</span>

Most Linux distributions follow FHS, with small variations:

* Some distributions do a **usrmerge**, where `/bin`, `/sbin` and `/lib` become symbolic links to the matching directories under `/usr`.
* Some enterprise distributions add extra directories for their management tools.
* Desktop distributions often organise application menus and desktop environments differently.

<blockquote class="infobox infobox--info">
💡 **Exam tip:** LPIC-1 expects you to know the standard directories and their main roles. Especially important: `/etc` (configuration), `/var` (variable data) and the differences between `/bin`, `/sbin`, `/usr/bin` and `/usr/sbin`.
</blockquote>

<span class="nb-accent">Understanding mounted filesystems</span>

An important Linux idea is “mounting” filesystems. Unlike Windows, where each drive gets a letter, Linux hangs every drive and partition into the existing directory tree.

* Important terms:
* Mount point: a directory in the filesystem where another filesystem is attached.
* Root partition: the primary partition mounted at `/`
* Mounting: the process of attaching a filesystem.

🔧 **Practical example**

When you plug in a USB stick, it is often mounted automatically at a path such as `/media/username/USB-NAME`. All files on the stick are then reachable under that path.

```bash
mount | grep media
/dev/sdb1 on /media/username/USB-STICK type vfat (rw,nosuid,nodev,...)
```

<blockquote class="infobox infobox--warn">
⚠️ **Important:** A mount point can be any directory — it does not have to be empty. If you mount a filesystem on a non-empty directory, the original contents are hidden for the duration of the mount and reappear only when you unmount.
</blockquote>

<span class="nb-accent">Key files for mounting</span>

**Two files control how filesystems are mounted:**

* `/etc/fstab` (*Filesystem Table*): which filesystems to mount automatically at boot
* `/etc/mtab` (*Mount Table*): a dynamic list of currently mounted filesystems

<blockquote class="infobox infobox--practice">
❗ **Typical mistake:** Unmounting a filesystem that is still in use leads to `device is busy`. Fix: stop every process that is using it, or use `-f` (force) — only with care.
</blockquote>

With that map of the Linux directory tree you can go deeper into navigation and filesystem operations. FHS looks busy at first, but it is a logical, consistent layout that will carry daily admin work.

## Basic navigation commands

With the layout in place, the next step is the commands you use to move around it. These are daily tools for every Linux administrator and show up often on LPIC-1.

<span class="nb-accent">Show the current directory (pwd)</span>

`pwd` (**p**rint **w**orking **d**irectory) prints the directory you are in:

```bash
pwd
/home/username/documents
```

<span class="nb-accent">It looks simple, but it matters for several reasons:</span>

* It orients you after several directory changes
* It shows the full path, not only the current folder name
* You can copy that path into scripts or other commands

🔧 **Practical example**

```bash
cd /var/log
pwd
/var/log
cd ../..
pwd
/
```

<blockquote class="infobox infobox--info">
💡 **Tip:** If your prompt already shows the current path, `pwd` can look redundant. The prompt may be shortened or relative. `pwd` always gives the full absolute path.
</blockquote>

<span class="nb-accent">List directory contents (ls)</span>

`ls` (**l**i**s**t) is one of the most used commands. In its simplest form it lists files and subdirectories in the current directory:

```bash
ls
Documents Downloads Music Pictures Videos
```

`ls` becomes useful through its options:

**Important ls options:**

| Option | Description | Example |
|---|---|---|
| `-l` | Long, detailed listing | `ls -l` |
| `-a` | Also show hidden files (starting with `.`) | `ls -a` |
| `-h` | Human-readable sizes (KB, MB, GB) | `ls -lh` |
| `-t` | Sort by last modification time | `ls -lt` |
| `-r` | Reverse sort order | `ls -ltr` |
| `-S` | Sort by file size | `ls -lS` |
| `-R` | Recurse into subdirectories | `ls -R` |

🔧 **Practical example: detailed listing with ls -la**

```bash
ls -la
total 84
drwxr-xr-x 14 username group 4096 May 10 15:24 .
drwxr-xr-x  3 root     root  4096 Mar  8 09:12 ..
-rw-------  1 username group 9807 May 10 14:30 .bash_history
-rw-r--r--  1 username group  220 Mar  8 09:12 .bash_logout
drwxr-xr-x  3 username group 4096 Apr 25 19:42 Documents
-rw-r--r--  1 username group 8980 May  9 11:02 report.pdf
```

The long listing (`ls -l`) breaks each file into these columns (left to right):

* **File type and permissions:** e.g. `drwxr-xr-x`
* **Hard-link count:** e.g. `14`
* **Owner:** e.g. `username`
* **Group:** e.g. `group`
* **Size:** in bytes (or human-readable with `-h`)
* **Timestamp:** date and time of last change
* **Name:** the entry name

<span class="nb-accent">File-type marker in the long listing (`ls -l`)</span>

The first character of the permission column identifies the file type:

| Character | File type | Meaning and typical use |
|:---:|---|---|
| `-` | Regular file | Ordinary files such as documents, scripts, binaries, images or archives. |
| `d` | Directory | Folders that hold references to other files and subdirectories. |
| `l` | Symbolic link (*soft link*) | A pointer to the path of another file or directory. |
| `b` | Block device | Hardware with buffered, block-wise access (e.g. disks `/dev/sda`, USB sticks). |
| `c` | Character device | Hardware with unbuffered byte-stream access (e.g. terminals `/dev/tty`, RNGs `/dev/urandom`). |
| `s` | Socket (*Unix domain socket*) | IPC endpoint for local network and system services. |
| `p` | Named pipe (FIFO) | Buffered channel that passes data between two processes. |

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Not every type is asked equally often, but regular files (`-`), directories (`d`) and symbolic links (`l`) are mandatory.
</blockquote>

<span class="nb-accent">File types and colour coding in the shell</span>

Many Linux distributions colour `ls` output for a quick visual scan:

| Colour | File type / state | Typical examples |
|---|---|---|
| **Blue** | Directories | `Documents/`, `Downloads/`, `/etc/` |
| **Green** | Executables and scripts | `script.sh`, `binary`, `installer` |
| **Red / magenta** | Compressed archives and media | `.tar.gz`, `.zip`, `.png`, `.jpg` |
| **Cyan** | Symbolic links | `vmlinuz -> boot/vmlinuz-6.8.0` |
| **Blinking red** | Broken symbolic links | Symlinks whose target does not exist (*dangling link*) |
| **Yellow on black** | Device files | `/dev/sda`, `/dev/null` |

<blockquote class="infobox infobox--info">
💡 **Tip:** Colour is handy for a quick scan, but it does not work in every terminal. For a reliable type check always use the first column of `ls -l` or the `file` command.
</blockquote>

<span class="nb-accent">Change directory (cd)</span>

`cd` (**c**hange **d**irectory) moves you to another directory. It is the basic navigation command:

```bash
cd /etc
```

`cd` has several practical forms:

**Important cd variants:**

| Command | Action |
|---|---|
| `cd /path/to/directory` | Change to an absolute path |
| `cd directory` | Change to a subdirectory of the current directory |
| `cd ..` | Move to the parent directory |
| `cd ../..` | Move two levels up |
| `cd ~` or bare `cd` | Move to the current user’s home directory |
| `cd -` | Move to the previous working directory (very useful) |
| `cd ~user` | Move to the given user’s home directory |

🔧 **Practical example**

```bash
pwd
/home/username
cd /var/log
pwd
/var/log
cd -
/home/username
cd -
/var/log
```

<blockquote class="infobox infobox--practice">
❗ **Typical mistake:** Trying to `cd` into a file instead of a directory produces an error.
</blockquote>

```bash
cd /etc/hosts
bash: cd: /etc/hosts: Not a directory
```

<span class="nb-accent">Hidden files and directories</span>

On Linux, hidden files and directories start with a dot (`.`). `ls` hides them unless you pass `-a`:

```bash
ls -a
. .config Downloads Pictures
.. .dbus .gnupg .profile
.bash_history Desktop .local Videos
.bash_logout Documents Music .Xauthority
.bashrc .mozilla .ssh
```

* The two special entries `.` and `..` have a fixed meaning:
* `.` (single dot): the current directory
* `..` (double dot): the parent directory

Those hidden entries exist in every directory and matter for relative paths.

* Typical hidden files and directories in a user’s home:
* `.bashrc`, `.bash_profile`: Bash configuration
* `.config/`: program configuration
* `.local/`: local application data
* `.ssh/`: SSH keys and configuration
* `.cache/`: cached application data

<blockquote class="infobox infobox--info">
💡 **Practice tip:** To list only hidden files you can use a pattern:
</blockquote>

```bash
ls -d .*
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** Deleting hidden files can have unexpected effects because they often hold important configuration. Check what they do first.
</blockquote>

<span class="nb-accent">Combining commands for efficient navigation</span>

In practice you combine these commands to move quickly and get an overview:

```bash
cd /etc && ls -l | grep network
drwxr-xr-x 6 root root 4096 Apr 12 10:34 network
-rw-r--r-- 1 root root 650 Nov 8 2023 networks
```

That command changes to `/etc` and then lists entries whose names contain `network`.

<blockquote class="infobox infobox--info">
💡 **Exam-prep tip:** For LPIC-1 you should not only know these navigation commands, you should have them by heart. Many practical tasks need them, and they underpin every later filesystem operation.
</blockquote>

Mastering these basics looks simple and is still a real step toward Linux administration. On real systems with deep trees and many files, efficient navigation is daily work.

## Working with paths

Paths are the “addresses” in the Linux filesystem. They point the way to a file or directory. You need a solid grasp of paths to work the command line and to run commands correctly.

<span class="nb-accent">Absolute vs. relative paths</span>

Linux has two basic kinds of path: absolute and relative.

* Absolute paths:
* Always start with a slash (`/`), which is the root directory
* Give the full route from the root to the target
* Work regardless of the current working directory
* Are unique and do not depend on where you stand

```bash
/home/username/Documents/report.pdf
/etc/ssh/sshd_config
/var/log/syslog
```

* Relative paths:
* Do not start with a slash
* Are relative to the current working directory
* Depend on where you are

```bash
Documents/report.pdf # relative to the current directory
../Downloads/file.zip # one directory up, then into Downloads
```

🔧 **Practical example**

Assume you are in `/home/username`:

```bash
pwd
/home/username
cat Documents/report.txt # relative path
cat /home/username/Documents/report.txt # absolute path (same result)
```

Both commands read the same file. The first uses a relative path from the current directory; the second uses the full absolute path.

<blockquote class="infobox infobox--info">
💡 **Tip:** Use absolute paths in scripts that must work from any working directory. Use relative paths in daily work to type less.
</blockquote>

<span class="nb-accent">The difference between . and ..</span>

Every directory has two special entries:

* `.` (single dot):
* The current directory
* Useful when you need to refer to it explicitly
* Helpful when you run a script or program from the current directory

```bash
./script.sh # run script.sh from the current directory
cp /etc/hosts ./ # copy hosts into the current directory
```

* `..` (double dot):
* The parent directory
* Lets you move “up” the tree
* Can be stacked to climb several levels

```bash
$ cd .. # one directory up
$ cd ../.. # two directories up
$ cp ../file.txt . # copy file.txt from the parent into the current directory
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** In the root directory (`/`), `..` still points at `/` because there is no level above it.
</blockquote>

```bash
cd /
pwd
/
cd ..
pwd
/
```

<span class="nb-accent">Home-directory shortcut (~)</span>

The tilde (`~`) is a shortcut for the current user’s home directory:

```bash
cd ~ # go home (same as cd with no arguments)
ls ~/Documents # list Documents in the home directory
```

You can combine the tilde with a username to reach that user’s home:

```bash
ls ~john/Documents # list John’s Documents directory
cd ~root # go to root’s home directory
```

<blockquote class="infobox infobox--practice">
❗ **Typical mistake:** The tilde is expanded by the shell, not by the kernel. In some contexts (certain config files or scripts) it is not expanded, which leads to broken paths.
</blockquote>

<span class="nb-accent">Paths with spaces and special characters</span>

Linux paths can contain spaces and special characters, but they need extra care or the shell will misread them.

**Ways to handle spaces:**

1. **Quotes:**

```bash
cd "My Documents"
cp "/home/username/Holiday 2023/Photos" .
```

1. **Escape with a backslash:**

```bash
cd My\ Documents
ls Holiday\ 2023/Photos
```

1. **Single quotes** (no expansion of specials such as `$` or `~`):

```bash
cd 'My Documents'
```

<blockquote class="infobox infobox--warn">
⚠️ **Important:** Many Linux administrators avoid spaces in file and directory names altogether and use underscores (`_`) or hyphens (`-`) instead. That makes command-line work much simpler.
</blockquote>

**Other awkward special characters:**

Some characters have special meaning in the shell and must be treated accordingly:

* `?`, `*`, `[`, `]` (wildcards)
* `$` (variable substitution)
* `&`, `;`, `|`, `<`, `>` (command control)
* `` ` ``

🔧 **Practical example**

```bash
# If a file literally named "file?.txt" exists (question mark in the name)
ls file\?.txt # escape the question mark
# If a directory name contains a $
cd 'directory$name'
```

<blockquote class="infobox infobox--info">
💡 **Exam tip:** LPIC-1 can ask you to handle special characters in filenames. Know the escape methods and when to use which.
</blockquote>

<span class="nb-accent">Using Tab completion efficiently</span>

Tab completion is one of the strongest tools for faster, cleaner command-line work. It saves time and cuts typos.

* Basic Tab completion:
* Start typing a command or path
* Press Tab
* If there is exactly one completion, it is inserted
* If there are several, a second Tab lists the options

```bash
cd /ho[TAB] # completes to "/home/"
cd /home/us[TAB] # completes to "/home/username/" if unique
```

**Richer Tab completion:**

**Command completion:** also works for commands

```bash
sys[TAB][TAB]
systemctl systemd-analyze systemd-run
```

**Option completion:** many commands complete their options too

```bash
ls --[TAB][TAB]
--all --directory --human-readable
--almost-all --dereference --inode
```

**Variable completion:** works for environment variables

```bash
echo $HO[TAB] # completes to $HOME
```

**Hostname completion:** on network-related commands

```bash
ssh server[TAB] # completes hostnames from known hosts
```

<blockquote class="infobox infobox--info">
💡 **Tip:** Tab completion also works on paths with spaces and special characters. It inserts the needed escapes or quotes. That is one of the best ways to handle awkward names.
</blockquote>

🔧 **Practical example: less typing with paths**

```bash
# Without Tab completion:
cp /var/log/apache2/error.log /home/username/backups/apache_error_20230514.log
# With Tab completion (much less typing):
cp /v[TAB]lo[TAB]ap[TAB]er[TAB] ~/ba[TAB]apache_error_20230514.log
```

<blockquote class="infobox infobox--warn">
⚠️ **Note:** Many possible completions can fill the screen. Type more characters to narrow the set before you press Tab again.
</blockquote>

<span class="nb-accent">Using paths efficiently in practice</span>

With absolute and relative paths plus the shortcuts, you can move around the tree more efficiently:

```bash
# Combined path shortcuts
cp ~/Documents/report.txt ../shared/
mv ./temp/* ~/archive/
find . -name "*.log" -exec cp {} ~/logs/ \;
```

<blockquote class="infobox infobox--practice">
❗ **Typical beginner mistake:** Many Linux newcomers mix up absolute and relative paths. If a command returns `No such file or directory` even though you know the file exists, check which path type you used.
</blockquote>

Efficient paths are a core skill on the command line. With practice, moving around the Linux filesystem becomes second nature — on the LPIC-1 exam and in daily admin work.

## Wildcards and patterns for efficient work

When you work with files you often want to touch several names at once. Instead of typing each name, wildcards (glob patterns) let you address whole groups. That is one of the strongest tools in the Linux kit.

<span class="nb-accent">Basic wildcards (* and ?)</span>

Linux supports two primary wildcards that work in almost every command-line situation:

* The asterisk (`*`)
* Matches any number of characters (including none)
* The most used wildcard
* Can sit anywhere in the name

```bash
ls *.txt # every file ending in .txt
ls report* # every file starting with "report"
ls *2023* # every file with "2023" somewhere in the name
ls /var/log/*.log # every log file in /var/log
```

* The question mark (`?`)
* Matches exactly one character
* Useful when you know or want to limit the length

```bash
ls report?.txt # matches e.g. "report1.txt", "reportA.txt", but not "report10.txt"
ls file??.txt # names with "file" plus exactly two more characters
ls /etc/rc?.d/ # matches rc0.d, rc1.d, rc2.d and so on
```

🔧 **Practical example**

Suppose a directory contains:

* report.txt
* report1.txt
* report2.txt
* report_final.txt
* presentation.ppt
* notes.txt

```bash
rm *.txt # deletes every file ending in .txt
cp report?.txt backup/ # copies report1.txt and report2.txt, but not report.txt or report_final.txt
```

<span class="nb-accent">Character classes with square brackets `[ ]`</span>

* Square brackets let you name specific characters or ranges:
* `[abc]` matches one character that is a, b or c
* `[a-z]` matches one lowercase letter
* `[0-9]` matches one digit
* `[a-zA-Z]` matches any letter (upper or lower)

```bash
ls file[123].txt # matches file1.txt, file2.txt, file3.txt
ls [a-c]*.txt # every .txt file starting with a, b or c
ls Report[A-Z]*.pdf # every PDF starting with "Report" plus an uppercase letter
```

**Character classes can be combined:**

```bash
ls [a-zA-Z0-9]*.conf # every .conf file starting with an alphanumeric character
```

<blockquote class="infobox infobox--info">
💡 **Tip:** Character classes are especially useful when you filter files by numbers or alphanumeric patterns, such as log files with dates in the name.
</blockquote>

<span class="nb-accent">Exclusion with negation `[! ]`</span>

An exclamation mark as the first character inside a class selects every character *except* the ones listed:

```bash
ls [!a]*.txt # every .txt file that does NOT start with 'a'
ls report[!0-9]*.pdf # PDFs starting with "report" followed by a non-digit
rm *[!.txt] # CAUTION! Does not do what you think — see the warning
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** That last example is dangerous and does not work as expected. It would delete files such as `file.txta` but leave `file.txt`. To delete everything except `.txt` files, use extended globbing or `find` with `-not`.
</blockquote>

<span class="nb-accent">Extended glob patterns</span>

Bash offers extended globbing beyond the standard wildcards. Enable it with:

```bash
shopt -s extglob
```

* With extended globbing you get these extra patterns:
* `?(pattern)`: zero or one occurrence of the pattern
* `*(pattern)`: zero or more occurrences
* `+(pattern)`: one or more occurrences
* `@(pattern1|pattern2|...)`: exactly one of the listed patterns
* `!(pattern1|pattern2|...)`: everything except the listed patterns

```bash
ls +(file|log)*.txt # every .txt file starting with "file" or "log"
rm !(*.txt|*.pdf) # delete every file EXCEPT .txt and .pdf
cp @(jan|feb|mar)_*.doc reports/ # copy only documents starting with jan_, feb_ or mar_
```

<blockquote class="infobox infobox--warn">
⚠️ **Exam tip:** LPIC-1 mainly asks the standard wildcards (`*` and `?`) and character classes (`[]`). Extended globs are useful to know and show up less often.
</blockquote>

<span class="nb-accent">Brace expansion — a related technique</span>

Brace expansion is not a wildcard. It generates text patterns. It is useful for operations on several similar names:

```bash
mkdir {2022,2023}-backup # creates 2022-backup and 2023-backup
touch file{1..5}.txt # creates file1.txt through file5.txt
cp report.{txt,pdf,docx} archive/ # copies report.txt, report.pdf and report.docx into archive/
mkdir -p backup/{jan,feb,mar}/{data,logs} # nested directory tree
```

Unlike wildcards, brace expansion runs before filename expansion and also works for names that do not exist yet.

<span class="nb-accent">Wildcards in daily work</span>

Typical cases that show how wildcards speed the job:

**Find log files from given days:**

```bash
grep "Error" /var/log/syslog.2023-05-*
```

**Find given file types in a tree:**

```bash
find . -name "*.conf" -type f
```

**List only scripts with a given name pattern:**

```bash
ls -l [a-z]*.sh
```

**Delete backup files:**

```bash
rm *~
rm *.bak
```

<span class="nb-accent">Typical wildcard pitfalls</span>

Wildcards have a few common failure modes:

<blockquote class="infobox infobox--practice">
❗ **Empty pattern:** If a pattern matches no file, most commands keep it as a literal:
</blockquote>

```bash
ls *.xyz # if no .xyz files exist, "*.xyz" is printed as a literal
rm *.xyz # error if no .xyz files exist
```

<blockquote class="infobox infobox--practice">
❗ **Pattern too wide:** Be especially careful with delete commands:
</blockquote>

```bash
rm * # deletes ALL files in the current directory
rm ./* # same as above
rm /* -rf # NEVER RUN THIS. It would destroy the system
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** For destructive operations such as `rm`, first test with `ls` which files the pattern matches.
</blockquote>

<blockquote class="infobox infobox--practice">
❗ **Hidden files are not matched:** The asterisk (`*`) does not match names that start with a dot:
</blockquote>

```bash
ls * # all non-hidden files
ls .* # hidden files, but also . and ..
ls -d .[!.]* # hidden files without . and ..
ls -a # all files including hidden files
```

<blockquote class="infobox infobox--practice">
❗ **Wildcards vs. quotes:** The shell expands wildcards before the command runs. To use a wildcard literally, escape it or quote it:
</blockquote>

```bash
grep "report*" file.txt # search for the literal text "report*" in file.txt
grep report\* file.txt # same as above
```

<blockquote class="infobox infobox--warn">
⚠️ **Exam tip:** LPIC-1 often asks you to find or change files by name pattern. Know the differences between `*`, `?`, `[...]` and `[!...]` — they sit under many practical scenarios.
</blockquote>

Fluent wildcards mark an experienced Linux user. A few keystrokes run complex file operations — on the exam and in daily administration.

## Creating and deleting files and directories

Once you can move around and find files, the next skills are creating them and removing them when needed. These operations are daily admin work and matter for LPIC-1.

<span class="nb-accent">Creating files (touch and its uses)</span>

`touch` is the simplest way to create empty files:

```bash
touch file.txt
touch protocol.log report.pdf notes.md
```

One command can create several files if you separate the names with spaces.

<blockquote class="infobox infobox--info">
💡 **What many people miss:** The real job of `touch` is not creating files, it is updating access and modification times. If the named file does not exist, it is created as a side effect.
</blockquote>

```bash
ls -l file.txt
-rw-r--r-- 1 username group 0 May 14 10:23 file.txt
touch file.txt
ls -l file.txt
-rw-r--r-- 1 username group 0 May 14 10:24 file.txt # note the updated time
```

**Useful touch options:**

| Option | Description | Example |
|---|---|---|
| `-a` | Update access time only | `touch -a file.txt` |
| `-m` | Update modification time only | `touch -m file.txt` |
| `-t` | Set a specific timestamp | `touch -t 202305141030 file.txt` |
| `-r` | Use another file’s timestamp | `touch -r ref.txt file.txt` |

🔧 **Practical example**

```bash
# Create a file with a given timestamp (14 May 2023, 10:30)
touch -t 202305141030.00 report.txt
# Stamp several files with the same time as a reference file
touch -r report.txt document1.pdf document2.docx
```

<blockquote class="infobox infobox--info">
💡 **Tip:** If you do not want to change the time of an existing file, use `-c`:
</blockquote>

```bash
touch -c existing_file.txt # updates the time only if the file exists
```

<span class="nb-accent">Other ways to create files</span>

Besides `touch` there are further methods:

**With redirections:**

```bash
echo "Hello world" > file.txt # create or overwrite the file
echo "New line" >> file.txt # append text
> empty_file.txt # create an empty file or truncate an existing one
```

**With editors:**

```bash
nano new_file.txt # open Nano on a new file
vim document.txt # open Vim on a new file
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** `>` overwrites an existing file with no warning. Be careful, especially in directories with important files.
</blockquote>

<span class="nb-accent">Creating directories (mkdir, recursive create)</span>

`mkdir` (**m**a**k**e **dir**ectory) creates new directories:

```bash
mkdir projects
mkdir documents pictures videos # several directories at once
```

By default `mkdir` can only create a directory if the parent already exists. With `-p` (parents) you can create a whole path in one go:

```bash
mkdir -p projects/2023/quarter1/reports
```

That command builds the full tree even if none of the intermediate directories exist.

🔧 **Practical example for nested directory trees**

```bash
# Project tree with several subdirectories
mkdir -p project/{src,docs,tests}/{main,backup}
# Result:
# project/src/main
# project/src/backup
# project/docs/main
# project/docs/backup
# project/tests/main
# project/tests/backup
```

**More useful mkdir options:**

| Option | Description | Example |
|---|---|---|
| `-m` | Set permissions on new directories | `mkdir -m 755 secure_dir` |
| `-v` | Verbose output (shows created directories) | `mkdir -v backup` |

<blockquote class="infobox infobox--info">
💡 **Tip:** Combining `-p` and `-v` shows which directories were actually created:
</blockquote>

```bash
mkdir -pv archive/2023/{jan,feb,mar}
# Output:
mkdir: created directory 'archive'
mkdir: created directory 'archive/2023'
mkdir: created directory 'archive/2023/jan'
mkdir: created directory 'archive/2023/feb'
mkdir: created directory 'archive/2023/mar'
```

<span class="nb-accent">Deleting files (rm and its options)</span>

`rm` (**r**e**m**ove) deletes files:

```bash
rm file.txt
rm report1.pdf report2.pdf # several files
rm *.tmp # every file ending in .tmp
```

**Important rm options:**

| Option | Description | Example |
|---|---|---|
| `-i` | Interactive (ask before deleting) | `rm -i important.txt` |
| `-f` | Force (no prompts, ignore missing files) | `rm -f *.bak` |
| `-r` or `-R` | Recursive (directories and their contents) | `rm -r old_project` |
| `-v` | Verbose (show deleted files) | `rm -v temp.txt` |

<blockquote class="infobox infobox--warn">
⚠️ **Important warning:** The Linux command line has no recycle bin. Files deleted with `rm` are gone immediately. Be extra careful with wildcards and `-f`.
</blockquote>

🔧 **Practical example: safer deletes**

```bash
# Interactive delete (asks for each file)
$ rm -i *.log
# Verbose output shows what is deleted
$ rm -v project/*.bak
```

<blockquote class="infobox infobox--practice">
❗ **Typical beginner mistake:** Combining `rm -rf` with wildcards or incomplete paths can be catastrophic. The notorious `rm -rf /` would try to wipe the filesystem (modern distributions have guards against that).
</blockquote>

<blockquote class="infobox infobox--info">
💡 **Safer default:** Many experienced administrators alias `rm` so it is interactive by default:
</blockquote>

```bash
alias rm='rm -i' # add this line to your .bashrc
```

<span class="nb-accent">Deleting directories (rmdir, rm -r)</span>

There are two main ways to delete directories:

**rmdir — empty directories only:**

```bash
rmdir empty_directory
rmdir folder1 folder2 # several empty directories
```

`rmdir` only removes empty directories. If the directory still holds files or subdirectories, you get an error:

```bash
rmdir non_empty_directory
# Output:
rmdir: failed to remove 'non_empty_directory': Directory not empty
```

**rm -r — directories with contents:**

```bash
rm -r project
```

With `-r` (recursive), `rm` deletes a directory and everything in it, including subdirectories and files.

🔧 **Practical example for safer directory deletes**

```bash
# Interactive delete of a directory (asks per file)
rm -ri old_project/
# Recursive delete; prompts only for write-protected files
rm -r old_project/
```

<blockquote class="infobox infobox--warn">
⚠️ **Important warning:** `rm -rf` is especially dangerous because it deletes recursively with no prompts. Use it only when you are sure of the target.
</blockquote>

<span class="nb-accent">Safety when deleting files</span>

Permanent deletes carry risk. Safer habits and alternatives:

**Safer alternatives to an immediate delete:**

**Move instead of delete:**

```bash
mkdir -p ~/trash
mv unwanted_file.txt ~/trash/
```

**Use helpers such as `trash-cli`:**

```bash
trash-put file.txt # move to the trash instead of deleting
trash-list # list trash contents
trash-restore # restore deleted files
```

**Test with `ls` before deleting:**

```bash
ls *.tmp # see which files would be affected
rm *.tmp # if the list is right, run the delete
```

**Use `find` with `-delete` for more precise deletes:**

```bash
find . -name "*.tmp" -type f -print # show first
find . -name "*.tmp" -type f -delete # then delete
```

<blockquote class="infobox infobox--info">
💡 **Practice tip:** Build scripts or aliases for frequent deletes that include extra safety checks.
</blockquote>

<blockquote class="infobox infobox--practice">
❗ **Important for LPIC-1:** Know the differences between `rm`, `rmdir` and `rm -r`, and what `-f`, `-i` and `-r` do. These commands show up often in practical exam tasks.
</blockquote>

Creating and deleting files and directories is core Linux work. With this section you can build filesystem trees and remove them again. Linux has no undo for deleted files — so treat deletes with care.

## Copying and moving files and directories

Copying and moving files and directories is among the most common Linux admin tasks. You duplicate, reorganise and rename — all required for LPIC-1 and daily work.

<span class="nb-accent">Copying files (cp and important options)</span>

`cp` (**c**o**p**y) creates duplicates of files:

```bash
cp source dest
cp report.txt report_backup.txt
cp /etc/ssh/sshd_config ~/backup/
```

You can copy several files into a target directory at once:

```bash
cp file1.txt file2.txt file3.txt target_directory/
cp *.jpg pictures/
```

**Important cp options:**

| Option | Description | Example |
|---|---|---|
| `-i` | Interactive (ask before overwriting) | `cp -i file.txt backup/` |
| `-v` | Verbose (show which files are copied) | `cp -v *.log logs/` |
| `-p` | Keep permissions, owner and timestamps | `cp -p important.txt backup/` |
| `-a` | Archive mode (like `-p`, plus links, recursive) | `cp -a source/ dest/` |
| `-u` | Update (copy only if source is newer or dest is missing) | `cp -u *.conf /etc/backup/` |
| `-n` | No clobber (do not overwrite existing files) | `cp -n *.txt backup/` |
| `-f` | Force (overwrite destinations without asking) | `cp -f critical.conf /etc/` |

🔧 **Practical example**

```bash
# Back up all config files, keep metadata, confirm overwrites
cp -ivp /etc/*.conf ~/config_backup/
# Copy only newer files (useful for incremental backups)
cp -uv ~/documents/*.docx ~/backup/documents/
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** By default `cp` overwrites existing destinations with no warning. Use `-i` if you want a prompt, or `-n` if existing files must never be overwritten.
</blockquote>

<blockquote class="infobox infobox--info">
💡 **Practice tip:** Many administrators alias `cp` with `-i` by default:
</blockquote>

```bash
alias cp='cp -i' # add this line to your .bashrc
```

<span class="nb-accent">Copying directories (cp -r)</span>

To copy a directory including its contents you need `-r` (recursive):

```bash
cp -r source_directory/ dest_directory/
```

Without `-r`, `cp` errors if you try to copy a directory:

```bash
$ cp documents/ backup/
# Output:
cp: -r not specified; omitting directory 'documents/'
```

<span class="nb-accent">Watch these cases when copying directories:</span>

**Destination does not exist:**

```bash
cp -r projects/ new_project/
# creates new_project/ and copies the contents of projects/ into it
```

**Destination already exists:**

```bash
$ cp -r projects/ existing_directory/
# copies projects/ as a subdirectory of existing_directory/
```

**Copy the contents, not the directory itself:**

```bash
$ cp -r projects/* existing_directory/
# copies only the CONTENTS of projects/ into existing_directory/
```

🔧 **Practical example for a more complex copy**

```bash
# Copy the tree but only .txt files
cp -r --parents $(find projects/ -name "*.txt") backup/
# keeps the directory structure, copies only the .txt files
```

<blockquote class="infobox infobox--info">
💡 **Tip:** `-a` (archive) is often better than `-r` when you want an exact duplicate, because it keeps permissions, owners, timestamps and symbolic links:
</blockquote>

```bash
cp -a source_directory/ dest_directory/
```

<span class="nb-accent">Moving files and directories (mv)</span>

`mv` (**m**o**v**e) moves files or directories from one place to another:

```bash
mv source dest_directory/
mv report.txt ~/documents/
```

Unlike `cp`, moving directories needs no extra option:

```bash
mv source_directory/ dest_directory/
```

**Important mv options:**

| Option | Description | Example |
|---|---|---|
| `-i` | Interactive (ask before overwrite) | `mv -i file.txt dest/` |
| `-v` | Verbose (show what is moved) | `mv -v *.log logs/` |
| `-u` | Update (move only if source is newer) | `mv -u *.dat new_place/` |
| `-n` | No clobber (leave existing files) | `mv -n *.conf /etc/` |
| `-f` | Force (overwrite without asking) | `mv -f old.txt new.txt` |
| `-b` | Backup (keep backups of overwritten files) | `mv -b file.txt dest/` |

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** Like `cp`, `mv` overwrites existing files with no warning by default. Use `-i` for a confirmation.
</blockquote>

🔧 **Practical example**

```bash
# Move all PDFs into the archive, confirm overwrites
mv -iv *.pdf ~/archive/
# Move only if the source is newer
mv -uv *.conf /etc/
```

<span class="nb-accent">Renaming files (with mv)</span>

Linux has no separate rename command for a single file. `mv` does that job too:

```bash
mv old_name.txt new_name.txt
```

Conceptually, renaming is moving to the same place under a different name.

```bash
# Rename a file
mv report_old.doc report_new.doc
# Rename a directory
mv old_project/ new_project/
```

<blockquote class="infobox infobox--info">
💡 **Tip for batch renames:**
</blockquote>

If you want to rename many files to a pattern, `rename` (or `prename` on some distributions) is more useful than `mv`:

```bash
# Turn all .txt files into .md
rename 's/.txt$/.md/' *.txt
# Lowercase all names
rename 'y/A-Z/a-z/' *
```

<blockquote class="infobox infobox--info">
💡 **Note that `rename` is not installed by default on every distribution and can behave differently depending on the package.**
</blockquote>

<span class="nb-accent">Typical mistakes and how to avoid them</span>

Copying and moving files keeps producing the same errors:

<blockquote class="infobox infobox--practice">
❗ **Wrong destination directory:**
</blockquote>

```bash
# WRONG: tries to copy every .txt file into a file named "Backup"
cp *.txt Backup
```

```bash
# RIGHT: copy into a directory named "Backup"
cp *.txt Backup/
```

The trailing slash makes the directory intent obvious. If `Backup` should be a directory, create it before you copy.

<blockquote class="infobox infobox--practice">
❗ **Unintended overwrite:**
</blockquote>

```bash
# Dangerous: can overwrite important files
cp important.conf /etc/
```

```bash
# Safer: ask before overwriting
cp -i important.conf /etc/
```

<blockquote class="infobox infobox--practice">
❗ **Ignoring error messages:**
</blockquote>

```bash
# Typical error when the destination directory is missing
$ cp file.txt missing_directory/
# Output:
cp: cannot create regular file 'missing_directory/file.txt': No such file or directory
```

Read the error. In this case create the destination first:

```bash
mkdir -p missing_directory/
cp file.txt missing_directory/
```

<blockquote class="infobox infobox--practice">
❗ **Swapping source and destination:**
</blockquote>

```bash
# WRONG: reversed order can lose data
$ cp important_data.txt empty_file.txt # overwrites important_data.txt with empty_file.txt
```

```bash
# RIGHT: source first, then destination
$ cp empty_file.txt important_data.txt
```

The order for `cp` and `mv` is always: `cp SOURCE DEST` or `mv SOURCE DEST`.

<blockquote class="infobox infobox--warn">
⚠️ **Operational note:** For critical copy or move jobs:
</blockquote>

* Use `-v` (verbose) so you see what happens
* Use `-i` (interactive) or `-n` (no-clobber) to protect against overwrites
* Test complex jobs first with `echo` or `ls`
* Take a backup of important data beforehand

🔧 **Practical example: test file operations safely**

```bash
# See which files would be affected
ls -l *.txt
# Simulate the command with echo
for f in *.txt; do echo "Would copy $f to backup/"; done
# If that looks right, run the real command
cp -iv *.txt backup/
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the differences between `-i`, `-f` and `-n` on `cp` and `mv`. Know when `cp` needs `-r` or `-a` and when it does not. These show up often in practical tasks.
</blockquote>

`cp` and `mv` are pillars of Linux filesystem work. With this section you can copy, move and rename files and directories — for LPIC-1 and for daily Linux use.

## Working with links

Linux filesystems have a powerful idea that Windows environments often misread: links. These special files point at other files or directories without copying them — essential for tidy trees and for saving space.

<span class="nb-accent">What are links in the Linux filesystem?</span>

Links are references to other files or directories. They let the same file appear under different names and in different places. Linux has two kinds:

* Hard links: direct references to a file’s content (its inode)
* Symbolic links (also soft links or symlinks): references to the path of a file or directory

Links sit deep in Linux system architecture. Many system files are actually links to other files, to avoid duplication and simplify maintenance.

<span class="nb-accent">Creating and understanding hard links (ln)</span>

Hard links are created with `ln` and no extra option:

```bash
ln source dest_hardlink
```

🔧 **Practical example**

```bash
echo "Important content" > original.txt
ln original.txt hardlink.txt
ls -l
# Output:
total 8
-rw-r--r-- 2 username group 17 May 14 11:20 hardlink.txt
-rw-r--r-- 2 username group 17 May 14 11:20 original.txt
```

Note the `2` after the permissions — that is the number of hard links to this file.

**Important properties of hard links:**

**Same inode**: a hard link and the original file point at the same inode (the same physical location on disk).

```bash
$ ls -i original.txt hardlink.txt
# Output:
1234567 hardlink.txt
1234567 original.txt # same inode number
```

* **No distinguished “original”**: there is no difference between the first name and its hard link — both are equal.
* **Content remains until the last link is removed**: deleting one name only removes that link; the content stays until the last link is gone.

```bash
$ rm original.txt
$ cat hardlink.txt
Important content # content is still there
```

* **Same permissions and owner**: permissions, owner and timestamps are identical for all hard links; a change applies to all of them.

<blockquote class="infobox infobox--warn">
⚠️ **Limits of hard links:**
</blockquote>

* They only work inside the same filesystem
* They cannot link directories (except for root, which is risky)
* They point at inodes, not paths, so there is no recorded “source”

<blockquote class="infobox infobox--info">
💡 **Tip:** Hard links shine when you need a 100% identical second name for a file without using extra disk space.
</blockquote>

<span class="nb-accent">Creating and understanding symbolic links (ln -s)</span>

Symbolic links (symlinks) are created with `ln -s`:

```bash
ln -s source symbolic_link
```

🔧 **Practical example**

```bash
echo "Content of the original file" > original.txt
ln -s original.txt symlink.txt
ls -l
# Output:
total 4
-rw-r--r-- 1 username group 25 May 14 11:30 original.txt
lrwxrwxrwx 1 username group 11 May 14 11:30 symlink.txt -> original.txt
```

<blockquote class="infobox infobox--info">
💡 **Note the leading `l` in the permissions and the arrow `->` pointing at the target.**
</blockquote>

**Important properties of symbolic links:**

* **Separate inode**: a symbolic link has its own inode that stores the path of the target

```bash
$ ls -i original.txt symlink.txt
1234567 original.txt
1234568 symlink.txt # different inode number
```

* **Points at a path, not an inode**: if the original is moved or renamed, the link breaks
* **Can cross filesystem boundaries**: works between disks/partitions
* **Can point at directories**: symbolic links can also link directories

```bash
$ ln -s /var/log logs
$ ls -l
lrwxrwxrwx 1 username group 8 May 14 11:35 logs -> /var/log
```

* **Own permissions**: symbolic links have their own permissions, which are usually ignored because access uses the target’s permissions

<blockquote class="infobox infobox--practice">
❗ **Typical failure — broken symbolic links:**
</blockquote>

```bash
ln -s original.txt symlink.txt
rm original.txt
ls -l
# Output:
lrwxrwxrwx 1 username group 11 May 14 11:40 symlink.txt -> original.txt
cat symlink.txt
# Output:
cat: symlink.txt: No such file or directory
```

The symbolic link still exists, but its target is gone.

<span class="nb-accent">Differences between hard links and symbolic links</span>

```markdown
┌─ Inode architecture: hard link vs. symbolic link ───────────┐
│ 1. Hard link (two directory entries share one inode):       │
│    [ file1.txt ] ───┐                                       │
│                     ▼                                       │
│                  [ Inode #1042 ] ───► [ Data blocks ]       │
│                     ▲                 ("content...")        │
│    [ file2.txt ] ───┘                                       │
│    (Link-Count = 2, same filesystem required)               │
├─────────────────────────────────────────────────────────────┤
│ 2. Symbolic link (own inode points to the target path):     │
│    [ symlink.txt ]                                          │
│           │                                                 │
│           ▼                                                 │
│    [ Inode #2099 ] ───► ("file1.txt" path)                  │
│                                │                            │
│                                ▼                            │
│    [ target.txt  ] ───► [ Inode #1042 ] ───► [ Data blocks ]│
│    (Works across filesystem boundaries)                     │
└─────────────────────────────────────────────────────────────┘
```

Side by side:

| Property | Hard link | Symbolic link |
|---|---|---|
| Inode | Identical to the original | Own inode (stores a path) |
| Filesystem boundaries | Same filesystem only | Across filesystem boundaries |
| If the original is deleted | Content remains | Link breaks |
| Directories | Not possible (except root) | Possible |
| Visibility | Not recognisable as a link | Visible as a link (`ls -l` shows the target) |
| Size | Same as the original | A few bytes (path length) |
| Permissions | Identical to the original | Own permissions, but access uses the target |

🔧 **Practical example: hard links vs. symlinks**

* Hard-link structure:
* File1 ---> [Inode #1234] <--- File2 (hard link)
* |
* v
* [Data blocks]
* Symlink structure:
* File1 ---> [Inode #1234] ---> [Data blocks]
* ^
* |
* Symlink ---> [Inode #5678] (holds the path to File1)

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** The differences between hard links and symlinks are asked often. Especially: what happens if you delete the original, and whether you can link across filesystems.
</blockquote>

<span class="nb-accent">Practical uses for links</span>

Links are not theory — they show up constantly in Linux operations:

<span class="nb-accent">Uses for hard links</span>

**Efficient backup:**

```bash
ln ~/important.txt ~/backup/important.txt
```

Saves space because both names share the same physical blocks.

**Several names for one configuration file:**

```bash
ln /etc/config.conf /etc/config.stable
```

Both names point at the same content; a change to one is a change to both.

**Shared data for several applications:**

```bash
ln /var/data/shared.db /opt/app1/data.db
ln /var/data/shared.db /opt/app2/data.db
```

Both applications use the same database.

**Uses for symbolic links:**

**Alternatives system:**

```bash
$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9 Apr 16 08:53 /usr/bin/python -> python2.7
```

Linux uses symlinks in the alternatives system to switch between software versions.

**Shorter paths:**

```bash
ln -s /var/www/html/very/long/path/to/website ~/website
```

Fast access to a deep directory.

**Versioned software:**

```bash
ln -s apache-tomcat-9.0.45 tomcat
```

You update the software by changing the symbolic link.

**Moving directories:**

```bash
# If /var is too small, move logs to another partition
mv /var/log /data/log
ln -s /data/log /var/log
```

Programs still look under `/var/log`, but the data lives elsewhere.

<span class="nb-accent">Identifying and managing links</span>

Finding and managing links needs specific commands and options:

**Identify links:**

```bash
# Spot symbolic links with ls
ls -l
lrwxrwxrwx 1 user group 11 May 14 11:50 symlink.txt -> original.txt
# Find hard links (every file with the same inode as "file.txt")
find /path -xdev -samefile file.txt
# Link details with stat
stat file.txt
```

**Deal with broken symbolic links:**

```bash
# Find broken links
find /path -type l -xtype l
# Update a symbolic link
ln -sf new_file.txt old_symlink.txt
```

<blockquote class="infobox infobox--info">
💡 **`-f` forces overwriting an existing symbolic link.**
</blockquote>

**Commands that treat links specially:**

**`cp`**: by default copies a symbolic link as a regular file unless you use `-a` or `-d`:

```bash
cp -a symlink.txt backup/ # copy the link as a link
cp symlink.txt backup/ # copy the content of the linked file
```

**`rm`**: deletes only the link, not the linked file:

```bash
rm symlink.txt # deletes only the link
```

**`find`**: can search for links:

```bash
find /path -type l # finds symbolic links
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch backups:** When you back up a directory that contains symbolic links, check how the backup tool treats them. Some follow links and store the targets; others store only the link.
</blockquote>

<blockquote class="infobox infobox--practice">
❗ **Typical mistake — recursive symbolic links:**
</blockquote>

A symbolic link that points, directly or indirectly, at a parent directory can create an endless loop:

```bash
mkdir -p test/subdir
cd test/subdir
ln -s .. loop
ls -la loop/subdir/loop/subdir/loop/
```

Commands such as `ls -R` or `cp -r` can recurse forever. Many modern tools detect those loops, but not all of them.

<blockquote class="infobox infobox--info">
💡 **Practice tip:** When you create symbolic links, decide whether the target should be a relative or an absolute path:
</blockquote>

* **Absolute paths** (`ln -s /path/to/file link`) work from anywhere, but break if the target is moved
* **Relative paths** (`ln -s ../file link`) only work while the relation between link and target stays the same, and they survive moving a whole tree

🔧 **Practical example: pick the right link type**

```bash
# Absolute paths for system-wide links
sudo ln -s /opt/jdk-11.0.11 /usr/local/jdk
# Relative paths for project links
cd ~/projects/webapp
ln -s ../shared/config config
```

<span class="nb-accent">Worked example: a typical Linux layout</span>

On many Linux systems you will see this:

```bash
ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9 Apr 16 08:53 /usr/bin/python -> python3
ls -l /etc/alternatives/editor
lrwxrwxrwx 1 root root 17 Mar 9 15:11 /etc/alternatives/editor -> /usr/bin/vim.basic
ls -li /usr/bin/gcc*
2884360 -rwxr-xr-x 1 root root 1014648 Jun 23 2023 /usr/bin/gcc
2884361 -rwxr-xr-x 3 root root 1014648 Jun 23 2023 /usr/bin/gcc-9
2884361 -rwxr-xr-x 3 root root 1014648 Jun 23 2023 /usr/bin/gcc-ar-9
2884361 -rwxr-xr-x 3 root root 1014648 Jun 23 2023 /usr/bin/gcc-nm-9
```

**What you see here:**

* `/usr/bin/python` is a symbolic link to `python3` (version switching)
* The default editor is a symbolic link through the alternatives system
* `gcc-9`, `gcc-ar-9` and `gcc-nm-9` are hard links to the same file (same inode 2884361)

That mix of symbolic links and hard links is typical of how Linux handles versions, alternatives and shared resources.

Links are a fundamental Linux filesystem idea and show up at several levels on LPIC-1. Knowing both types, and their trade-offs, lets you organise the tree properly.

## Why this matters for LPIC-1

Filesystem navigation and efficient file handling are not theory — they sit under almost every task you will do as a Linux administrator. For LPIC-1 they matter for several reasons:

<span class="nb-accent">Exam relevance</span>

* On LPIC-1 exam 101, filesystem work is a core topic
* Up to 25% of the questions relate directly or indirectly to navigation and file operations
* The exam mixes theory questions and practical scenarios
* Correct use of wildcards, links and command options is asked often
* Relative vs. absolute paths are often embedded in larger tasks

<blockquote class="infobox infobox--info">
💡 **Exam tip:** Commands such as `ls`, `cp`, `mv`, `ln` and their options should be automatic. Examiners like tasks that combine elementary commands in non-trivial situations.
</blockquote>

## Resources and exam information

As in the first module, here are the key facts on learning materials and sitting LPIC-1.

<span class="nb-accent">Study materials</span>

Several solid resources are available for LPIC-1 prep:

* **Official LPI materials**: the Linux Professional Institute publishes [learning materials](https://learning.lpi.org/en/learning-materials/all-materials/){.badge-link-text} aligned with the exam topics
* **Books**: specialist titles such as “[LPIC-1. Sicher zur erfolgreichen Linux-Zertifizierung](https://www.rheinwerk-verlag.de/lpic-1-sicher-zur-erfolgreichen-linux-zertifizierung/){.badge-link-text}” from Rheinwerk cover the exam topics and often include a simulator
* **Courses**: providers offer full trainings, for example the [10-day LPIC-1 course](https://www.qualiero.com/lerninhalte/classroom-trainings/linux-lpi-komplettausbildung-zur-lpic-1-101-und-102.html){.badge-link-text} for modules 101 and 102

<span class="nb-accent">Exam format and requirements</span>

LPIC-1 consists of two separate exams:

* **LPIC-1 Exam 101**: system architecture, Linux installation and package management, GNU and Unix commands, devices and filesystems
* **LPIC-1 Exam 102**: shells and shell scripts, user interfaces, administrative tasks, system services, networking fundamentals and security

Each exam has 60 questions (multiple choice and fill-in) and a 90-minute time limit. You need at least 500 of 800 points to pass.

## Command Reference (Cheatsheet)

| Command | Syntax / option | Role and use |
|---|---|---|
| `pwd` | `pwd [-P]` | Print the current working directory (`-P` physical path without symlinks) |
| `cd` | `cd [path] / cd -` | Change directory (`cd -` jumps back to the previous directory) |
| `ls` | `ls -la / ls -lh` | List directory contents (including hidden files and human-readable sizes) |
| `touch` | `touch [file]` | Create an empty file or update access/modification timestamps |
| `mkdir` | `mkdir -p dir/sub` | Create directories (`-p` recursively, including parents) |
| `cp` | `cp -r / cp -a` | Copy files (`-r` directories, `-a` keep permissions/timestamps) |
| `mv` | `mv [source] [dest]` | Move or rename files and directories |
| `rm` | `rm -rf [target]` | Delete files (`-r` recursive, `-f` without confirmation) |
| `rmdir` | `rmdir [directory]` | Delete empty directories only |
| `ln` | `ln [source] [link]` | Create a hard link to the same inode on the same filesystem |
| `ln` | `ln -s [source] [link]` | Create a symbolic link (soft link) to a path |
| `stat` | `stat [file]` | Show inode metadata, permissions, timestamps and link count |
| `file` | `file [file]` | Detect the real MIME/file type regardless of the extension |

## Further Resources

| Resource | Description |
|---|---|
| [Filesystem Hierarchy Standard (FHS 3.0)](https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html){.badge-link-text} | Official Linux Foundation specification for the Linux directory tree |
| [GNU Coreutils: Directory Operations](https://www.gnu.org/software/coreutils/manual/html_node/Directory-operations.html){.badge-link-text} | Official reference for `mkdir`, `rmdir`, `pwd`, `ls` and path handling |
| [GNU Coreutils: Basic Operations](https://www.gnu.org/software/coreutils/manual/html_node/Basic-operations.html){.badge-link-text} | Manual for `cp`, `mv`, `rm`, `ln` and link handling |
| [LPI 101: Topic 103 Objectives](https://www.lpi.org/our-certifications/exam-101-objectives/){.badge-link-text} | Official LPIC-1 objectives for GNU and Unix commands |

## Conclusion

Reliable navigation and precise file management are the foundation of Linux administration. With FHS, wildcards and inode knowledge of hard links and symlinks, you have the main practical tools for LPIC-1 exam 101.

The next LPIC-1 module covers command-line text processing: [LPIC-1: Text Processing with Shell Commands](/en/online-courses/lpic-1-serie/2025/2025-05-28-lpic-1-text-processing-with-shell-commands){.badge-link-text} – how you process data streams with `grep`, `sed`, `awk`, `cut` and `sort`.

**Course overview:** [All LPIC-1 articles and modules](/en/category/lpic-1-serie){.badge-link-text}
