Symlink

1. Goal

Understand what ln -s does on Linux, when to use it, and how to verify it safely from the terminal.

2. Why this matters in real jobs

Symlinks are everywhere in real environments:

  • Pointing /var/www/current to the active release in a deploy (blue/green style)

  • Making config paths stable (e.g., linking a service to a versioned config file)

  • Avoiding duplication while keeping predictable paths (scripts, systemd units, CI runners)

If you don’t understand symlinks, you’ll break deploys, copy files unnecessarily, or debug the wrong path.

3. Minimal theory

  • ln creates a link.

  • -s means symbolic link (a “symlink”) — basically a pointer to another path.

  • A symlink is like a shortcut: it stores the target path, and the OS resolves it when you access the link.

  • If the target moves or is deleted, the symlink becomes broken (it still exists, but points nowhere).

Also: there are hard links (without -s), but for now: symlinks are what you’ll use most day-to-day.

4. Plan (step-by-step)

  1. Create a small test directory and file.

  2. Create a symlink with ln -s.

  3. Inspect the symlink using ls -l and readlink.

  4. Prove behaviour by reading through the link and then breaking the target.

  5. Learn the safe overwrite patterns you’ll use at work.

5. Practice (commands + exercises with full breakdown)

A) Create a test area (host-safe)

mkdir -p ~/lab-links && cd ~/lab-links
echo “hello” > original.txt

Breakdown

  • mkdir = make directory

    • -p = “parents”; don’t error if it exists, create missing parents too
  • ~/lab-links = path under your home directory (safe)

  • && = only run the next command if the previous succeeded

  • cd = change directory

  • echo "hello" > original.txt

    • > redirects stdout into a file (overwrites)

Keyboard shortcuts (terminal fluency)

  • Ctrl+L clears the screen (NOTE: frequently used)

  • Ctrl+A jump to start of line; Ctrl+E end of line

  • / Ctrl+P previous command; Ctrl+R reverse search history (NOTE)

Self-service lookup

  • man ln

  • ln --help

  • man bash (for && and redirection), or help cd


ln -s original.txt link.txt

What this does
Creates link.txt as a symbolic link pointing to original.txt.

Breakdown (every word)

  • ln = link command

  • -s = “symbolic”; make a symlink instead of a hard link

  • original.txt = target (the thing you want to point to)

  • link.txt = link name (the new shortcut path)

Keyboard shortcuts

  • Tab completion: type orig then press Tab to complete filenames

  • Alt+. (or Esc then .) inserts last argument of previous command — handy when reusing paths

Verify

ls -l
cat link.txt

Breakdown

  • ls lists directory contents

    • -l = long listing (shows link arrows like link.txt -> original.txt) (NOTE)
  • cat prints file contents — it follows the symlink transparently

Self-service lookup

  • man ls / ls --help

  • man cat / cat --help


readlink link.txt
readlink -f link.txt

Breakdown

  • readlink prints what a symlink points to

  • -f = follow recursively and canonicalise (resolve to an absolute “real” path where possible)

Keyboard shortcuts

  • Ctrl+W deletes the word behind the cursor (fast edits)

  • Ctrl+U clears to start of line; Ctrl+K clears to end of line

Self-service lookup

  • man readlink

  • readlink --help


D) Show what happens when the target disappears

rm original.txt
cat link.txt
ls -l link.txt

What you’ll see

  • cat link.txt should fail: “No such file or directory” because the link points to a missing target.

  • ls -l link.txt will still show the arrow, but it’s now broken.

Breakdown

  • rm removes a file (dangerous outside a lab)

  • Here it’s safe because we’re in ~/lab-links.

Keyboard shortcuts

  • Ctrl+C cancels a running/blocked command (NOTE)

  • Ctrl+D sends EOF (useful to exit shells or end input)

Self-service lookup

  • man rm / rm --help

When updating a symlink to point to a new target, you’ll often use:

ln -sfn newtarget link.txt

Breakdown

  • -s symlink

  • -f force (remove existing destination if needed)

  • -n treat destination that is a symlink as a normal file (prevents weird behaviour when link points to a dir)

Production note
This is a common release-switch trick: update a single stable path to a new version atomically-ish (often combined with mv patterns). Always verify after.

Self-service lookup

  • man ln then search for -n and -f (in man, press / then type -n)

6. Mini review + checklist

  • ln -s TARGET LINKNAME creates a symbolic link

  • ls -l shows LINK -> TARGET

  • cat LINK reads the target content transparently

  • ✅ If TARGET is removed, LINK becomes broken

  • ✅ Use readlink / readlink -f to inspect resolution

7. Control questions with answers (job-like scenarios)

  1. Scenario: Your deploy script expects /opt/app/current to always point at the active release folder (/opt/app/releases/2026-02-26-1200). You need to switch to a new release with minimal risk.
    Answer: Use a symlink:
  • ln -sfn /opt/app/releases/NEW /opt/app/current
    Then verify: readlink -f /opt/app/current and a health check.
  1. Scenario: A service reads /etc/myapp/config.yaml, but you want to keep versioned configs in /etc/myapp/configs/config-2026-02.yaml and switch between them.
    Answer: Make /etc/myapp/config.yaml a symlink to the chosen version, then restart/reload the service and confirm it reads the new config (logs + behaviour).

  2. Scenario: Someone deleted the target file but the symlink still exists. A build now fails with “No such file or directory” even though the path exists.
    Answer: Check with ls -l and readlink. Fix by recreating the target or repointing the symlink.

8. Small homework task with answers

Task (realistic lab):
Create a “current config” symlink and rotate it.

  1. In ~/lab-links, create config-v1.yaml and config-v2.yaml with different contents.

  2. Make config.yaml symlink to config-v1.yaml.

  3. Switch config.yaml to point to config-v2.yaml using a safe overwrite pattern.

  4. Verify which version is active using both cat and readlink -f.

Answer (commands)

cd ~/lab-links
echo “version: v1” > config-v1.yaml
echo “version: v2” > config-v2.yaml

ln -s config-v1.yaml config.yaml
cat config.yaml
readlink config.yaml

ln -sfn config-v2.yaml config.yaml
cat config.yaml
readlink config.yaml
readlink -f config.yaml

Next best action (1–3)

  1. Practise the difference between symlinks vs hard links: run ln original hardlink and compare stat output.

  2. Learn safe file/path inspection: stat, file, realpath, readlink -f.

  3. Tie it to container or lab workflows: use a symlink in ~/.local/bin to switch between tool versions while keeping a stable path for scripts or automation.

Discovery question
When you update a symlink used by a running service, how do you prove the service has picked up the new target — logs (journalctl), process open files (lsof), or a reload (systemctl reload) — and what’s your rollback plan?