Search code examples
pythonpython-2.7python-os

python os.listdir hitting OSError: [Errno 13] Permission denied


I'm trying to use os.listdir to grab a list of subdirectories but am running into an issue when I'm lacking permissions for one of these subdirectories. I can not gain permission so I'd like to continue as gracefully as possible. Ideally, I'd be able to ignore any directory I do not have permission to and return any others so as to not miss any child directories.

I've tried using os.walk but I ran into a number of other issues (performance included) and have decided not to use it.

An example. In the root directory there are 3 children, a, b, c

root dir
|
----> dir a 
|
----> dir b
|
----> dir c

I have permissions to a and c but not b (not known ahead of time). I'd like to return [a, c]

Here's the code with some generalizations-

def get_immediate_subdirectories(directory):
"""Returns list of all subdirectories in
directory

Args:
  directory: path to directory

Returns:
  List of child directories in directory excluding 
  directories in exclude and any symbolic links

"""
exclude = ["some", "example", "excluded", "dirnames"]
sub_dirs = []
try:
    all_files = os.listdir(directory)
except OSError:
    # **Ideally I'd be able to recover some list here/continue**
for name in all_files:
    if name in exclude:
        continue
    full_path = os.path.join(directory, name)
    if os.path.isdir(full_path):
        # Keep these separate to avoid issue
        if not os.path.islink(full_path):
            sub_dirs.append(name)
return sub_dirs

Solution

  • The assumption made in this question -- that a non-readable entry partway through a directory can cause os.listdir() to fail, and that a partial result consisting of other entries is possible -- is false.

    Observe:

    >>> import os
    >>> os.mkdir('unreadable.d')
    >>> os.chmod('unreadable.d', 0)
    >>> result = os.listdir('.')
    >>> print result
    ['unreadable.d']
    

    It's only trying to run listdir() on the unreadable directory itself that fails:

    >>> os.listdir('unreadable.d')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 13] Permission denied: 'unreadable.d'