Right, let’s talk about links. No, not the “save the princess” kind. The kind that saves you from having to make a dozen copies of the same file all over your filesystem, wasting precious disk space and your sanity. We’re talking about hard links and symbolic (or soft) links. The ln command is your tool here, and it’s deceptively simple. The difference between ln and ln -s is the difference between a clone and a shortcut, and getting it wrong can lead to some properly confusing situations.

The Core Idea: What’s an inode, Anyway?

To understand links, you have to understand what a filename really is. We think of a file as its name, but the system thinks of it as an inode. An inode is the file’s actual identity—it’s the metadata storehouse holding all the important info: permissions, ownership, timestamps, and, crucially, pointers to the data blocks on the disk where your content lives.

The filename? That’s just a human-friendly label pointing to an inode. A single inode can have multiple filenames pointing to it. And that, my friend, is the entire concept of a hard link.

When you create a hard link, you’re creating another directory entry (another filename) that points to the exact same inode. It’s not a copy. It’s a second name for the exact same content. The system treats all names equally; there is no “original” anymore.

Let’s get our hands dirty. Let’s create a file and then a hard link to it.

# Create a file with some deeply important content
echo "My brilliant research paper." > original.txt

# Now create a hard link. The syntax is: ln <target> <link_name>
ln original.txt hard_link.txt

# Let's see what we've got
ls -li

That ls -li (list with inodes and long format) is key. You’ll see something like this:

5894633 -rw-r--r--  2 you  staff  28 May 22 10:00 hard_link.txt
5894633 -rw-r--r--  2 you  staff  28 May 22 10:00 original.txt

Look at that. Both files share the same inode number (5894633). The second column shows the link count—it’s 2 for both! They are literally the same entity wearing different hats.

Why this is awesome: Change the content via one name, and the other reflects it instantly because it’s the same data. Delete original.txt? The data isn’t gone! The link count just drops to 1, and you can still access it perfectly through hard_link.txt. The data is only truly deleted when the link count hits zero.

The massive caveat (and it’s a dealbreaker): Hard links only work within the same filesystem. You cannot hard link a file on your boot drive to a file on your external USB drive. The inode numbers are only unique per-filesystem. Also, you can’t (typically) hard link to a directory. The designers wisely locked that down to prevent endless recursion nightmares in filesystem tools.

A symbolic link (or symlink), created with ln -s, is a different beast. It’s a special file that contains a path to another file. It’s a signpost. It doesn’t point to an inode; it points to a name.

# Create a symlink. The syntax is: ln -s <target> <link_name>
ln -s original.txt sym_link.txt

ls -li

Now the output looks different:

5894633 -rw-r--r--  1 you  staff  28 May 22 10:00 original.txt
5894634 lrwxr-xr-x  1 you  staff   12 May 22 10:02 sym_link.txt -> original.txt

Different inode (5894634). The link count for the target didn’t change. And there’s that helpful little arrow showing you where it points. Notice the first character is an l for “link”.

Why this is also awesome: Symlinks can point across filesystems! They can point to directories! They’re incredibly flexible.

Why this is a potential nightmare: It’s a signpost, not the destination. If you delete the original file (original.txt), your symlink becomes dangling. It points to a path that no longer exists. Using it will result in “No such file or directory”. If you move the target file, the symlink breaks. It’s fragile. Also, because it’s a redirection, there’s a tiny performance hit (utterly negligible for most things, but it exists).

Best Practices and Pitfalls

  1. What to Use When: Use hard links when you need durability and want multiple names for the same immutable data on the same filesystem (e.g., backing up file trees without copying). Use symlinks for everything else: linking config files into your home directory, creating shortcuts to deep directory structures, or linking across devices.

  2. The Absolute Path Trap: When creating symlinks, consider using absolute paths (ln -s /home/you/data/file.txt link). If you use a relative path (ln -s ../file.txt link), the link’s meaning changes if you move the symlink itself to a different directory. The link resolves relative to its own location, not the location where you ran the ln command. This trips everyone up.

  3. The Great Recursion Caper: Be careful with symlinks in scripts. If you’re traversing a directory tree, you need to handle symlinks to directories or you might end up in an infinite loop. Tools like find have options (-L, -P) to control this behavior.

  4. They’re Not for Windows: If you’re sharing filesystems with Windows machines (like a network drive), symlinks might not be supported or might require special permissions, while hard links will be completely invisible and confusing. It’s a world of pain. Best to avoid links in shared environments altogether.

So, there you have it. ln for creating inseparable clones. ln -s for creating useful, if slightly fragile, signposts. Choose wisely based on whether you need a doppelgänger or a directions.