使用Python查找损坏的符号链接
如果我在一个坏掉的symlink
(符号链接)上调用os.stat()
,Python会抛出一个OSError
的异常。这让我们可以用它来找到这些坏掉的链接。不过,os.stat()
也可能因为其他一些原因抛出类似的异常。那么,有没有更准确的方法可以在Linux下用Python检测坏掉的symlink
呢?
9 个回答
os.lstat() 这个函数可能会对你有帮助。如果 lstat() 成功了,而 stat() 失败了,那很可能是因为这个链接坏掉了。
这不是原子操作,但它可以正常工作。
os.path.islink(filename) and not os.path.exists(filename)
实际上,通过阅读手册,我们可以看到
os.path.exists(path)
如果路径指向一个存在的文件,就返回True。如果是损坏的符号链接,则返回False。
手册中还提到:
在某些平台上,如果没有权限执行os.stat()来检查请求的文件,这个函数可能会返回False,即使路径实际上是存在的。
所以,如果你担心权限问题,应该添加其他条件来处理。
在Python编程中,有一句常见的说法是“请求原谅比请求许可更容易”。虽然我在现实生活中不太喜欢这个说法,但在很多情况下确实适用。通常,你应该避免在同一个文件上连续进行两个系统调用,因为你不知道在这两个调用之间,文件会发生什么事情。
一个常见的错误是写出这样的代码:
if os.path.exists(path):
os.unlink(path)
第二个调用(os.unlink)可能会失败,如果在你进行if测试后,文件被其他程序删除了,这样就会抛出一个异常,导致你后面的代码无法执行。(你可能会觉得这种情况在现实中不会发生,但我们上周刚刚在代码中发现了一个这样的bug——这个bug让几个程序员困惑了几个月,他们甚至称之为“海森堡bug”)
所以,在你的具体情况下,我可能会这样做:
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
这里的麻烦在于,stat函数对不存在的符号链接和损坏的符号链接返回的是相同的错误代码。
所以,我想你别无选择,只能打破原子性,做一些像这样的事情:
if not os.path.exists(os.readlink(path)):
print 'path %s is a broken symlink' % path