Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find broken symlinks with Python

If I call os.stat() on a broken symlink, python throws an OSError exception. This makes it useful for finding them. However, there are a few other reasons that os.stat() might throw a similar exception. Is there a more precise way of detecting broken symlinks with Python under Linux?

like image 346
postfuturist Avatar asked Aug 21 '08 19:08

postfuturist


People also ask

How do I find a symbolic link in Python?

islink() method in Python is used to check whether the given path represents an existing directory entry that is a symbolic link or not. Note: If symbolic links are not supported by the Python runtime then os. path. islink() method always returns False.

How do I fix a broken symlink?

The only way to fix these broken symlinks is by deleting them. Your system contains hundreds of dangling links and no one has the time to check for these links manually. In such cases, Linux tools and commands prove to be really helpful.

What are broken symlinks?

A symlink is broken (or left dangling) when the file at which it points is deleted or moved to another location.


1 Answers

A common Python saying is that it's easier to ask forgiveness than permission. While I'm not a fan of this statement in real life, it does apply in a lot of cases. Usually you want to avoid code that chains two system calls on the same file, because you never know what will happen to the file in between your two calls in your code.

A typical mistake is to write something like:

if os.path.exists(path):     os.unlink(path) 

The second call (os.unlink) may fail if something else deleted it after your if test, raise an Exception, and stop the rest of your function from executing. (You might think this doesn't happen in real life, but we just fished another bug like that out of our codebase last week - and it was the kind of bug that left a few programmers scratching their head and claiming 'Heisenbug' for the last few months)

So, in your particular case, I would probably do:

try:     os.stat(path) except OSError, e:     if e.errno == errno.ENOENT:         print 'path %s does not exist or is a broken symlink' % path     else:         raise e 

The annoyance here is that stat returns the same error code for a symlink that just isn't there and a broken symlink.

So, I guess you have no choice than to break the atomicity, and do something like

if not os.path.exists(os.readlink(path)):     print 'path %s is a broken symlink' % path 
like image 185
Thomas Vander Stichele Avatar answered Sep 26 '22 12:09

Thomas Vander Stichele