Symbolic Links 101
Symbolic links, also called “soft links” and “symlinks,” are a form of shortcuts that can point to files and directories. A symlink looks just like a regular file or directory in a file manager window. It also shows up as an entry in a file listing in a terminal window. The file or directory to which the symlink points can be anywhere in the file system tree.
For example, let’s say you have a symlink in your home directory called “dave-link” that points to a file called “text-file.txt” located somewhere else in the file system tree. Commands you use on the symlink are automatically applied to the file to which it points. If you try to use cat or less on the symlink, you’ll actually see the contents of the “text-file.txt” file.
A standard Linux installation contains many symlinks. Even if you don’t create any yourself, the operating system uses them. Application installation routines often use symlinks to point to executables files. When the software is updated, the binary file is replaced with the new version, and all the symlinks carry on working as before, as long as the new file’s name is the same as the old.
We can easily see some symlinks by using ls in the root directory. Some of the entries are displayed in a different color—on our Ubuntu 20.10 test machine, they’re displayed in light blue.
We type the following:
We can take a deeper look by using the -l (long listing) option. We type the following command to look at all the “lib” entries and the single “bin” entry:
At the start of each line is an “l,” which indicates the item is a symlink. The text after “->” shows at what the symlink is pointing. In our example, the targets are all directories.
The permissions are listed as read, write, and execute for the owner, the group, and others. These are default fake entries. They don’t reflect the actual permissions on the objects at which the symlinks point. It’s the permissions on the target file or directory that take precedence and are honored by the file system.
Broken Symlinks
A symlink is broken (or left dangling) when the file at which it points is deleted or moved to another location. If an application’s uninstallation routine doesn’t work properly, or is interrupted before it completes, you might be left with broken symlinks.
If someone manually deletes a file without knowing symlinks point to it, those symlinks will no longer work. They’ll be like road signs pointing to a town that’s been bulldozed.
We can easily see this behavior using a symlink called “hello” in the current directory. We type the following, using ls to see it:
It points to a program called “htg” in a directory called “bin.” If we “run” the symlink, it executes the program for us:
We can now check if this is what is happening by running the program directly:
As expected, we get the same response. Let’s delete the program file:
Now, when we look at the symlink, we see it’s listed in red because Linux knows it’s broken. It also tells us at what it used to point, so we can replace the file, recompile the program, or do whatever is necessary to repair the symlink.
Note that if we try to run the symlink, the error we get references the symlink name, rather than the name of the program to which the symlink points.
We type the following:
Finding Broken Symlinks
Most modern versions of find have the xtype (extended type) option, which simplifies finding broken symlinks. We’ll use the l flag with xtype, to tell it to search for links. Using find and xtype as follows, without any of the other type flags, forces xtype to return broken links:
Running the command in our test home directory finds quite a few broken symlinks. Note that the search is recursive by default, so it searches all subdirectories automatically.
The “hello” symlink we broke on purpose is listed, as we expected. One of the other symlinks is related to the Firefox browser, and the rest are associated with snaps.
If we pipe the output through wc with the -l (lines) option, we can count the lines, which is the same as counting the broken symlinks.
We type the following:
We’re informed that we have 24 broken symlinks pointing to nothing.
Find, Review, and then Remove
Before you rush in and delete all broken symlinks, look through the results of the find command. See if there’s a valid reason for any of the broken symlinks.
Sometimes, the symlink might be the problem, rather than the target file. If the symlink was created incorrectly it might point to nothing, but the real target is present. Re-creating the symlink would be the fix in that case.
It’s also possible that an apparently broken symlink is being used as something else, such as an indicator of a file lock or other go/no go indicator. Firefox does this; that’s what the first symlink in our list is. Firefox isn’t used on our test machine, though, so it’s safe for us to delete it.
It’s also possible the target is only present periodically, and this is the expected (and desired) behavior of that particular software. Maybe the target file is copied from another machine or the cloud, it performs its function, and is then deleted again, only to be replaced by a different program in the next cycle.
The broken symlink might also be a symptom of a software installation that failed. In that case, instead of deleting the symlink, you should either manually fix it or repeat the installation.
When you’ve fixed the broken links you need to keep, repeat the command to perform the search. The fixed symlinks should then be absent from the search results.
For safety’s sake, it’s best to limit your symlink removals to your own directories. Be extremely wary of running these commands as root, or on system directories.
Removing Broken Symlinks
The -exec (execute) option runs commands on the find search results. We’re going to use rm to delete each broken symlink. The {} string is replaced with the name of each broken symlink as each one is discovered by find.
We have to use a semicolon (;) to terminate the list of commands we want -exec to run. We’ll use a backslash () to “escape” the semicolon, so it’s treated as part of the find command, rather than something Bash should act on.
We type the following:
We’re returned to the command prompt with no indication that anything has happened. To verify the broken links have been removed, we repeat the command to look for them, as follows:
There aren’t any matching results, which means the broken symlinks have been removed.
Remember to Review First
Again, always take the time to review a list of symlinks before you run the command to delete them. You can avoid deleting any you’re unsure about by running the command to delete them in the appropriate directories.
For example, above, we could have run the command in the “.snap” directory, and then manually removed the solitary “hello” symlink. This would have left the Firefox lock symlink untouched.