Skip to content

Instantly share code, notes, and snippets.

@grubberr
Last active May 14, 2018 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grubberr/f88e6b9f92c26e9f638e4c7a81cdd5ab to your computer and use it in GitHub Desktop.
Save grubberr/f88e6b9f92c26e9f638e4c7a81cdd5ab to your computer and use it in GitHub Desktop.
file system walk which can go very deep ( no recursion limit )
#!/usr/local/bin/python3
import os
import logging
logger = logging.getLogger(__name__)
def commonpath(d1, d2):
" returns the length of longest common leading component "
i = 0
m = min(len(d1), len(d2))
while i < m:
if d1[i] != d2[i]:
break
i += 1
return i
def to_list(path):
path = os.path.normpath(path)
if path == os.path.sep:
return ['']
return path.split(os.path.sep)
def to_string(path):
if path == ['']:
return os.path.sep
return os.path.sep.join(path)
def chdir(cwd, new_dir):
" chdir from cwd new new_dir "
common_len = commonpath(cwd, new_dir)
for _ in range(len(cwd) - common_len):
os.chdir('..')
cwd = cwd[:common_len]
for d in new_dir[common_len:]:
try:
os.chdir(d)
except FileNotFoundError as e:
logger.error("%s: '%s'", e.strerror, os.path.join(to_string(cwd), e.filename))
break
cwd.append(d)
return cwd
def walk_chdir(top):
top = to_list(os.path.realpath(top))
stack = [top]
keep_cwd = os.getcwd()
cwd = keep_cwd.split(os.path.sep)
while stack:
new_dir = stack.pop()
cwd = chdir(cwd, new_dir)
if cwd == new_dir:
scandir_it = os.scandir()
for entry in scandir_it:
yield (to_string(cwd), entry)
if entry.is_dir(follow_symlinks=False):
stack.append(cwd + [entry.name])
os.chdir(keep_cwd)
top = '/var'
for (cwd, entry) in walk_chdir(top):
if entry.is_symlink():
print(os.path.normpath(os.path.join(cwd, entry)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment