【问题标题】:python os.listdir hitting OSError: [Errno 13] Permission deniedpython os.listdir 命中 OSError: [Errno 13] Permission denied
【发布时间】:2017-07-15 15:36:40
【问题描述】:

我正在尝试使用 os.listdir 来获取子目录列表,但是当我缺少这些子目录之一的权限时遇到了问题。我不能获得许可,所以我想尽可能优雅地继续。理想情况下,我可以忽略任何我无权访问的目录并返回任何其他目录,以免错过任何子目录。

我曾尝试使用 os.walk,但遇到了许多其他问题(包括性能)并决定不使用它。

一个例子。根目录下有3个孩子,a,b,c

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

我对 a 和 c 有权限,但对 b 没有权限(事先不知道)。我想返回 [a, c]

这是一些概括的代码-

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

【问题讨论】:

  • listdir() 在遇到您无法读取的单个文件时不会失败 - 只有在您正在阅读的目录中没有 +r 时才会失败,或者+x 在它的父母身上;其中文件或目录的权限无关紧要。
  • ...所以,如果您从os.listdir() 收到 OSError,则没有什么可恢复的——如果您的目录中没有 +r,您将无权读取 任何它的内容。
  • 关于os.path.isdir()os.path.islink(),顺便说一句,它们都只使用系统调用stat(2);在 MacOS 上,可能导致 EACCES 的唯一方法是,如果目录 holding 的路径的一个组件没有 +x - 所以如果你有 +r 但没有目录上的+x,那么listdir() 会成功,但其内容上的os.path.isdir() 会失败。

标签: python python-2.7 python-os


【解决方案1】:

遍历目录,先检查是否有访问权限:

for (dirpath, dirnames, filenames) in os.walk('/path/to/folder'):
    for dir in dirnames:
        path = os.path.join(dirpath, dir)
        read_write = os.access(path, os.W_OK) and os.access(path, os.R_OK)
        # W_OK write True and R_OK read True
        if not read_write:
            continue

见:Determining Whether a Directory is Writeable

【讨论】:

  • os.walk() 使用与os.listdir() 相同的系统调用——尽管它不会返回任何无法静默读取的内容,而不是引发异常。
【解决方案2】:

在这个问题中所做的假设 - 目录中途的不可读条目可能导致 os.listdir() 失败,并且由其他条目组成的部分结果是可能的 - 是错误的。

观察:

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

它只是试图在不可读的目录本身上运行 listdir() 失败:

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

【讨论】:

  • 所以可以肯定地说,如果我遇到这个错误,我可以通过返回一个空列表这样简单的事情来处理它
  • 谢谢!我只是在这里看link,并没有想到看看它是如何真正处理权限的
  • 出于好奇,是什么阻止您捕获异常并在那里处理它(例如,通过执行return []continue)?
【解决方案3】:

您必须更改文件的所有权:

$ sudo chown -R <userwhorunpython>:<userwhorunpython> <yourdirectory> 

如果它不起作用,请运行:

$ sudo chmod -r 777 directory

查看chmodchown 手册了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-21
    • 2012-06-16
    • 2016-08-07
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    相关资源
    最近更新 更多