You probably have heard of "hard link" (
ln) and "symbolic link" (
ln -s). You may have some vague idea that these commands have something to do with linking a file to another file... or something like that. This article will clarify the differences between
ln -s and provide some use cases.
To get the most out of this, I strongly encourage you to code along as you read. Meaningful reading is not passive. It is an active act where you, the reader, must also put in the work to get the most out of this article.
As much as you can, do lots of experiments on your own: try different variations of a command, repeat the command without looking at the article, and repeat it again the next day to fortify your memory (you'll be surprised at how fast you forget things!).
If you have Googled "hard vs soft link" in the past, you might have seen a reference to an "inode". An inode is a file's unique serial number. When you create a new file (
touch newfile.txt), you are actually creating an inode and a link to that inode. That file that you just created consists of at least two parts: an inode (a unique identifier) and a file name.
Let's create a file,
test1.txt. Inside it, add some texts:
touch 'hello test1' >> test1.txt
Aight, you created a file. Now let's create a hard link - let's call it
hard1.txt. Remember - when you create a new hard link, you are creating a new link to the inode of the original file.
ln test1.txt hard1.txt
ls -l. You should see two files displayed: a
test1.txt and a
hard1.txt. If you run
cat hard1.txt, you'll see that it has the same content as
Next, add a line into
echo "Hello again test1" >> test1.txt
You'll see "Hello again test1" inside both
hard1.txt. Changing the original file changes the hard link file as well!
What if we change the content of
hard1.txt instead? Let's find out!
echo "Hello from hard1" >> hard1.txt
You should see "Hello from hard1" text inside both
text1.txt. So changing either the original or the hard link file changes the other.
Finally, let's see what happens if we delete the original file,
hard1.txt is still there and the text inside hasn't changed. Great!
Let's recap. When you created
test1.txt, you created an inode. It contained "hello test1" initially. This inode (I'll call it "test1 inode") is connected to a file name
test1.txt. When you ran
ln test1.txt hard1.txt, you created a new file name,
hard1.txt, connected to the test1 inode. Think of test1 inode like an underground rabbit's burrow.
hard1.txt are the two holes connecting that burrow to the surface. From the outside, we see two holes. If you remove one hole, the bunny can still go out from the other hole. If you create a new hard link, you are just creating a third hole to the same, existing burrow. If you delete the
test1.txt burrow, it won't affect
hard1.txt at all! The only way to remove it is to completely remove all references to the inode. You need to remove all the hard links.
A few things that I'd like you to do:
- We've deleted
test1.txtbut we still have
hard1.txt. Create another hard link out of
hard1.txt, name it
anotherhard1.txt. What do you expect to happen? What does this tell you about the
rmcommand? (It doesn't really "delete" the file. It actually deletes a link to an inode)
hard1.txtto another name,
hardy1.txt. What is the relationship between
- Modify the content of one of the hard links. What do you think will happen to the content of the rest of the links?
- When do you think a hard link might come in handy? What is the use case?
- By the way, if you want to see the inode of a file, you can use
ls -i hard1.txt. Compare the inode number of a file vs its hard link and the inode number of a file vs its symlink (do this one later after you read the symlink section). You will find that the hard link has the same inode number as the original link and that a symlink has a different inode number as the original link.
Don't go to the next section yet. Spend some time creating your own hard links. Modify them. Do things that weren't covered in this section.
Unlike a hard link that points a file to an inode, a symbolic link (sometimes known as a soft link) connects by a file name, not an inode. Because it doesn't connect to an inode like that underground rabbit burrow analogy and it only connects on the surface level, their connection is "softer / weaker" than hard links (that's how I think about it anyway). As a result, by simply changing the name of the original file, you destroy its connection.
Create a new file
test2.txt and add a line into it:
echo "hello test2" >> test2.txt
Now create a symlink:
ln -s test2.txt soft2.txt
If you check the content inside
soft2.txt, you'll notice that they are one and the same. Good.
Let's update the content:
echo "hello soft2" >> soft2.txt cat soft2.txt cat test2.txt echo "hello original" >> test2.txt cat soft2.txt cat test2.txt
Notice that updating either the symlink file or the original file updates the other file. So far symlink acts like a hard link.
Now here comes the kicker. If you either change the name of the original file or remove the original file (
rm test2.txt), it will break the connection.
rm test2.txt cat soft2.txt cat: soft2.txt: No such file or directory
Retrospectively, if you had renamed the original file:
mv test2.txt somethingelse2.txt cat soft2.txt cat: soft2.txt: No such file or directory
However, if you instead had removed the symlink file instead and kept the original file, the content of the original file is preserved.
rm soft2.txt cat test2.txt # content is still there
Spend some time to play around with symlinks. Do the things that I didn't mention in this section. Learn by breaking things.
Here are some things to think about:
- Can you create a soft link out of a soft link?
- What would happen if you move the location of the original file to a different directory (but keep the same name)?
- Can you create a soft link out of a hard link?
- Can you create a hard link out of a soft link?
- Create a symlink and a hard link from a file. Do different things to each. Notice how they differ.
Now that you know what the differences between
ln -s are, let's talk about usage.
One usage for a symbolic link is to create portable dotfiles. I use Vim as a text editor. Vim can be configured with a
.vimrc file and a
.vim/ directory in the root directory. But what if I want to keep my dotfiles portable and my config files source-of-truth inside
Before learning about
ln, I used to copy-paste the
vimrc file and
vim/ directory from my dotfiles into the root directory. But if I copy-paste them, anytime I make changes to
~/.vimrc, I would have to apply the same change to my
~/Projects/iggy-dotfiles/vimrc file (I can also use
rsync, but that still requires a manual syncing). That's not good. I want to change either
~/Projects/iggy-dotfiles/vimrc and have the other file to update automatically - wait a second... this sounds like symlink!
A better way is to run:
rm ~/.vimrc ln -s ~/Projects/iggy-dotfiles/vimrc ~/.vimrc
With this, each time I make changes to either dotfiles vimrc or root vimrc, the content will always be the same. Btw, you can also use a symlink on a directory, so
ln -s ~/Projects/iggy-dotfiles/vim/ ~/.vim should work.
By the way, you could've also used a hard link, but the popular convention is to use symlink. If I ever need to delete a file, I can just delete
~/Projects/iggy-dotfiles/vimrc and my
~/.vimrc will automatically become obsolete. Having only one source of truth makes it easier to keep track of where things are. If you used a hard link, you'll have to remember to delete all of your vimrc sources.
You can use this technique with any config files like
On the other hand, hard links are useful for backups. For example, if you have a directory full of books:
aesop_fables.pdf bradbury_fahrenheit.pdf calvin_institutes.pdf darwin_origin.pdf ...
Assume that you need to create multiple directories so you can sort them based on author and title. It doesn't make sense to copy all your books into the directory
authors/ and once more in
title/. It makes more sense if you keep the original books, then create a hard link twice (remember, creating a hard link barely takes up any space). Inside the
authors/ directory you can have your books named and sorted by author. Inside the
title/ directory you can name and sort them by title. You can "duplicate" and "sort" your data as many ways as you want and they will barely take up any space.
We've reached the end. Thanks for making it this far. Hopefully by now you've understood
ln -s and put this knowledge to good use. Keep learning and happy coding!