Linux find broken symlinks

will give me all symbolic links, but makes no distinction between links that go somewhere and links that don’t. I’m currently doing:

find ./ -type l -exec file <> \; | grep broken 

13 Answers 13

I’d strongly suggest not to use find -L for the task (see below for explanation). Here are some other ways to do this:

    If you want to use a «pure find » method, and assuming the GNU implementation of find , it should rather look like this:

find . -type l ! -exec test -e <> \; -print 
find . -type l -exec sh -c 'file -b "$1" | grep -q "^broken"' sh <> \; -print 

The find -L trick quoted by solo from commandlinefu looks nice and hacky, but it has one very dangerous pitfall: All the symlinks are followed. Consider directory with the contents presented below:

$ ls -l total 0 lrwxrwxrwx 1 michal users 6 May 15 08:12 link_1 -> nonexistent1 lrwxrwxrwx 1 michal users 6 May 15 08:13 link_2 -> nonexistent2 lrwxrwxrwx 1 michal users 6 May 15 08:13 link_3 -> nonexistent3 lrwxrwxrwx 1 michal users 6 May 15 08:13 link_4 -> nonexistent4 lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/ 

If you run find -L . -type l in that directory, all /usr/share/ would be searched as well (and that can take really long) 1 . For a find command that is «immune to outgoing links», don’t use -L .

1 This may look like a minor inconvenience (the command will «just» take long to traverse all /usr/share ) – but can have more severe consequences. For instance, consider chroot environments: They can exist in some subdirectory of the main filesystem and contain symlinks to absolute locations. Those links could seem to be broken for the «outside» system, because they only point to proper places once you’ve entered the chroot. I also recall that some bootloader used symlinks under /boot that only made sense in an initial boot phase, when the boot partition was mounted as / .

So if you use a find -L command to find and then delete broken symlinks from some harmless-looking directory, you might even break your system.

Источник

announcement - icon

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

Читайте также:  Настроить свой прокси сервер linux

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

1. Overview

In this tutorial, we’ll see how to find broken symlinks using the find command in different forms.

Symlinks, symbolic links, or even soft links are files that point to other links, files, directories, and resources. They are similar to shortcuts in Windows.

Since they are links, once the target is not available anymore, they become useless.

Our examples will run in the following directory structure:

baeldung linux commands find broken symlinks test environment

To reproduce the above environment, we can run these commands in an empty directory:

mkdir -p baeldung/dir-1/dir-2/dir-3/ touch baeldung/file.txt touch baeldung/dir-1/file-1.txt touch baeldung/dir-1/dir-2/file-2.txt touch baeldung/dir-1/dir-2/dir-3/file-3.txt ln -s dir-2/dir-3/ baeldung/dir-1/dir-3 ln -s ../../file-1.txt baeldung/dir-1/dir-2/dir-3/file-1.txt ln -s baeldung/nonexistent-directory baeldung/dir-1/dir-2/link-to-nonexistent-directory ln -s dir-4/file-4.txt baeldung/dir-1/dir-2/dir-3/file-4.txt ln -s dir-2/file-2.txt baeldung/dir-1/file-2.txt ln -s ../filex.txt baeldung/dir-1/filex.txt ln -s ../cyclic-link baeldung/dir-1/cyclic-link ln -s dir-1/cyclic-link baeldung/cyclic-link ln -s . baeldung/infinite-loop

The find command has the following structure:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point. ] [expression]

The -H, -L and -P options control how symbolic links are treated, and when omitted, use -P as the default.

When -P is used and find examines or prints information from a symbolic link, the details are taken from the properties of the symbolic link itself.

We’re going to assume a Bash shell for our commands.

3.1. The Simple Way

The simplest way to detect broken symlinks is by using the following command:

Executing the above command in our environment will produce the following output:

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links baeldung/dir-1/filex.txt baeldung/dir-1/dir-2/link-to-nonexistent-directory baeldung/dir-1/dir-2/dir-3/file-4.txt

In the first two lines, we can see that not only we’re detecting broken symlinks, but we’re also reporting cyclic links. After the cyclic links, we see our broken links.

We used the -xtype l argument, which is true only for broken symbolic links.

We could have achieved the same thing by including the -P flag:

As we might guess, this means that -P is the default.

Читайте также:  Arch linux new kernel

3.2. The Portable Way

For POSIX-compliant shells, we can use the solution below since -xtype may not be available on all systems:

find baeldung -type l ! -exec test -e <> \; -print

As expected, the output will be the same as the last sample:

baeldung/cyclic-link baeldung/dir-1/cyclic-link baeldung/dir-1/filex.txt baeldung/dir-1/dir-2/link-to-nonexistent-directory baeldung/dir-1/dir-2/dir-3/file-4.txt

Let’s break in parts what is happening here:

  • The find command is looking for files of type link the same way we did in the last samples
  • ! is negating the result of the –exec expression that is testing for files existence – negating that will show only files that don’t exist
  • The exec expression action is used to execute commands for each found file. In this case, we’re executing test -e for each file. test is a Linux command used to check file types and compare values. Using the -e argument, we’re checking if the file exists
  • <> will be replaced by the current filename
  • \ is used to protect the command from expansion by the shell – the command can be quoted to avoid the use of “\
  • ; represents the end of the command
  • -print prints the result to the standard output

3.3. The Portable and In-Depth Way

Or, we can find this standard solution on many websites:

In fact, it works even better than other solutions above. This is because it also reports “file system loops” as we can see on the second line:

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links find: File system loop detected; ‘baeldung/infinite-loop’ is part of the same file system loop as ‘baeldung’ find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links baeldung/dir-1/dir-3/file-4.txt baeldung/dir-1/filex.txt baeldung/dir-1/dir-2/link-to-nonexistent-directory baeldung/dir-1/dir-2/dir-3/file-4.txt

The side effect that many people don’t know is that this approach does an in-depth search if a link points to a directory.

For example, imagine that we have a link that points to /usr/share. Using the -L option will make find traverse the entire /usr/share structure.

This approach can take too much time and resources to complete. In most cases, it is not what we’re trying to do. It’s essential to know when to use each approach and have in mind its benefits and consequences.

So, if we want to search for broken links inside directories when we have links that point to directories, we can use the -L option.

But if we want to stay inside our specific directory structure and don’t want to follow links, we don’t need to use -L.

To see this difference, we can enable the debug to show each file and folder visited:

find -D search baeldung -xtype l
find -D search -L baeldung -type l

3.4. The Hacky Way

We can use a different approach that uses the user permission level to read files.

Читайте также:  Эмулятор sony ps3 linux

It’s a bit of a hack since we’ll see broken links as well as files we don’t have permission to read. In other words, this option only really is applicable for root users.

That said, we can use the below command to find broken links:

find baeldung -type l ! -readable

That will produce an output similar to the last sample:

baeldung/cyclic-link baeldung/dir-1/cyclic-link baeldung/dir-1/filex.txt baeldung/dir-1/dir-2/link-to-nonexistent-directory baeldung/dir-1/dir-2/dir-3/file-4.txt

In this case, we used -type l that looks for files of type symlinks.

Then we negate the -readable argument with !. This will then show files that we can’t read.

Since we can’t read broken links, these are returned as part of the result.

3.5. Limiting the Scope and Depth

We can limit the scope of our search using some useful test expressions:

  • lname pattern: We can provide link name patterns
  • ilname pattern: The same as lname, but is case-insensitive
  • maxdepth: Search until this directory depth
  • mindepth: Search from this directory depth

As an example, we can execute:

find baeldung -mindepth 3 -ilname "*.TXT" -xtype l

Which will produce the output:

baeldung/dir-1/dir-2/dir-3/file-4.txt

3.6. Customizing the Output

We can customize the output to provide more useful information.

With the expression action -ls, we can have detailed information about the link and to where it points to:

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links 21109100 0 lrwxrwxrwx 1 fabio fabio 12 Sep 17 23:26 baeldung/dir-1/filex.txt -> ../filex.txt 21109086 0 lrwxrwxrwx 1 fabio fabio 30 Sep 17 23:21 baeldung/dir-1/dir-2/link-to-nonexistent-directory -> baeldung/nonexistent-directory 21109087 0 lrwxrwxrwx 1 fabio fabio 16 Sep 17 23:21 baeldung/dir-1/dir-2/dir-3/file-4.txt -> dir-4/file-4.txt

This approach doesn’t work well when filenames are unusual, because they can contain any character except \0 and /, even line breaks.

Unusual characters in a file name can do unexpected and often undesirable things to our terminal. For example, certain characters can change the settings of our function keys on some terminals.

4. Conclusion

In this quick article, we saw how to find broken links using simple and more elaborate approaches, how to limit the scope of the search, and customize the output.

The find utility is a real swiss army knife! To learn more, please take a look at the find man page.

Источник

Оцените статью
Adblock
detector