ln: hard links (by default), and symlinks (with the flag -s), but what is the difference between them?Symlinks, also called symbolic links or soft links, just store the filepath of file they point to, and the operating system transparently resolves the symlink when an application wants to access a file from its filepath.
This means that if a symlink /foo points to /bar, and /bar doesn't exist, applications will be told that the file /foo doesn't exist even though that's an existing symlink. It also means that you if you move the file around, the symlink won't know it has been moved and will stop pointing to an existing file.
Hard links are another term for the filepath itself. Files, also called "inodes" in this context, can be accessed by a filepath, also called a "hard link." Every file has at least one hard link: its initial filepath.
When you create additional hard links, what happens is now the same inode can be accessed from multiple filepaths. Most of the data of the file is in the inode, not in the hard link. For example, the contents of the file are inside the inode. This means if you modify a text file or image file that has multiple hard links to it, all hard links now point to the updated data, since they all point to the same inode and the text or image data is inside the inode.
Additionally, RWX file permissions are stored in the inode, not in the hard link. If you make a file read-only by removing the write permission, all hard links will appear as read-only in file managers, for example. Otherwise you would have a file that can't be modified from one filepath but can be modified by a different filepath.
Since a file needs a filepath to be accessed, a file without any filepaths can't be accessed at all. In other words, when we remove all hard links to a file, the system realizes it's now impossible for any program to access the file, so there is no point in keeping its data in disk. When you delete all hard links to a file, that deletes the file. This can also be called a reference counting mechanism. When the number of references (hard links) becomes zero, the data is deleted.
Advantages of Hard Links over Symlinks
Auto-updated: you can move the original file without making the hard link invalid, since a hard link doesn't point to the filepath of the original hard link, it points to the inode itself. You can't do the same with symlinks. If you move the file the symlink points to, the symlink will resolved to a non-existing file, so in order to move the file you need to update all symlinks.
Resilient: if you have two hard links to the same file, deleting one hard link, even the original hard link, doesn't delete the file from the disk. The file is only deleted when it has zero hard links left. By contrast, if you delete the file a symlink points to, the symlink stops working. This means that if, for some reason, you have a large file that you keep in multiple different locations, and those locations may move around sometimes, you can just create a hard link and not worry about it.
Advantages of Symlinks over Hard Links
Portable: a symlink is just a filepath which means it works on any filesystem and even across filesystems. By contrast, a hard link requires a filesystem that supports the concept of hard links. For example, it seems FAT doesn't support hard links, so you can't create a hard link on a FAT filesystem. Additionally, if you have two partitions, or two disks (an SSD and a HDD, for example), you can't create a hard link from one to another because their filesystems are separate, but you can create a symlink because files on both filesystems can be access via filepaths, and if it can be accessed by a filepath, it can be a symlink.
Easier to manage: a symlink is considered to be a different "type" of a file (or, more specifically, of entry in a directory), so it's possible to tell when something is a symlink. It's not possible to tell when something is a hard link because all filepaths to a file are hard links, including the original filepath when the file only has one hard link. In other words, hard links just appears as "files." There is a method to tell how many hard links a single file has, but we can't tell which hard link is the original filepath and which ones are the extra hard links we created. As a consequence, if we start using hard links everywhere, we may end up in a situation where we have a file, we delete it to save space, but it does nothing because there is an additional hard link somewhere that we forgot about. You need to come up with some rules to help manage hard links.
Can be jumped to: another advantage of symlinks is that file managers can display an option in the context menu to go to the location of the symlinked file. This opens the directory in which the symlinked file is contained.
Can link to a directory: symlinks can be used with directories, while hard links generally can't. The main reason for this is that most algorithms that traverse the file system would become infinitely more complex if hard links to directories existed, and if they weren't made more complex, then they would be prone to terrible bugs. For example, if hard links can't be distinguished from the original filepath, then a directory with two hard links inside two different directories has two different parent directories. If you can put a parent directory inside a child directory, you have created a loop in your filesystem. Every algorithm would have to keep track of all inodes they visit instead of just quickly checking the filepaths. If an algorithm has to traverse the entire filesystem it has to keep remember it has visited all directories it vists just to avoid visiting them twice. If it doesn't, and there is a loop, the algorithm will get stuck in an infinite loop until it runs out of memory or you give up waiting for it to finish. Symlinks don't have this problem because you can tell a symlink apart from a hard link.
Can link to another link: a symlink can symlink another symlink, while a hard link can't. When a symlink symlinks a symlink, the system resolves all the symlinks when an application requests a file. For example, /foo points to /bar, and /bar is also a symlink and it points to /baz, then accessing /foo accesses /baz. This allows you to add a layer of indirection to your symlinks. For example, if you have a directory full of symlinks that always point to the current version of something, and multiple places that need the current version that point to these symlinks, when a version changes, all you need to do is update your intermediary symlinks.
Observation: it seems you can create a hard link of a symlink, but there doesn't seem to be a way to modify an existing symlink. The only way to modify a symlink is by deleting it and creating a new one, which means updating a hard linked symlink doesn't update the other hard links, as it's not modifying the contents of the symlink inode, it's removing the hard link, creating a new symlink inode, and then creating a new hard link for that new symlink inode.