There are lots of broken links in my system. I wrote a script to relink all broken links. But, after the scripts runs, find would again show me that the links still exists.
This is my code:
find /home/saman -lname '/home/saman/*' -exec \
sh -c 'ln -snf "/home$(readlink "$0")" "$0"' {} \;
After running the command above, I search for broken links and still find them:
find . -type l | xargs file | grep broken
What am I doing wrong?
Best Answer
The first problem is that your
find
command will only find links that used full paths, not relative ones. To illustrate:In the example above, I created two broken links. The first used an absolute path and the second, a relative one. If I now try your
find
command (having itecho
the relinking command instead of running it so we can see what it's doing), only one of the two will be found:The second issue is that your path is wrong. You are recreating links as
"/home$(readlink "$0")" "$0"
. Thereadlink
command will already show the full path so adding/home
to it results in/home/home/...
which is not what you want.More importantly, what you are attempting is not possible. If a link is broken, that means that its target does not exist. Since the target doesn't exist, you can't simply relink the file, there's nowhere to link it to. The only thing you could do is recreate the link's target. This, however, is unlikely to be very useful since it would simply make your broken links point to new, empty files. If that is indeed what you want to do, you could try
Finally, you might want to create a more complex script that i) finds all broken links ii) searches your machine for files with the same name as the target of the link iii) presents you with a list of them and iv) asks you which one it should now link to.