I'm using os.walk
with followlinks=True
, but I hit a place where a symbolic link refers to it's own directory, causing an infinite loop. The culprit in this case is /usr/bin/X11
which list listed as follow :
lrwxrwxrwx 1 root root 1 Apr 24 2015 X11 -> .
Is there any way to avoid following links to either .
or ..
which I would assume, would cause similar problems? I think I could check this with os.readlink
then compare against the current path. Is there any other solution for this?
Use os. walk() to recursively traverse a directory For each subdirectory in the directory tree, os.
Python's built-in os. walk() is significantly slower than it needs to be, because – in addition to calling os. listdir() on each directory – it executes the stat() system call or GetFileAttributes() on each file to determine whether the entry is a directory or not.
OS. walk() generate the file names in a directory tree by walking the tree either top-down or bottom-up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).
setrecursionlimit(limit) does is: Set the maximum depth of the Python interpreter stack to limit. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python.
There is no way to avoid storing a set of all the directories visited, if you want to avoid recursion. You do not need to use readlink
, however, you can just store inodes. This avoids the problem of path canonicalization altogether.
import os
dirs = set()
for dirpath, dirnames, filenames in os.walk('.', followlinks=True):
st = os.stat(dirpath)
scandirs = []
for dirname in dirnames:
st = os.stat(os.path.join(dirpath, dirname))
dirkey = st.st_dev, st.st_ino
if dirkey not in dirs:
dirs.add(dirkey)
scandirs.append(dirname)
dirnames[:] = scandirs
print(dirpath)
To completely avoid the problem of infinite recursion (with links pointing to where ever) you need to store the files and/or directories you already visited.
The people from pynotify module had the same issue and used the described method. The patch is in the link ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With