在python中检查文件的权限

Posted

技术标签:

【中文标题】在python中检查文件的权限【英文标题】:Check the permissions of a file in python 【发布时间】:2015-02-10 15:11:27 【问题描述】:

我正在尝试检查给定路径的文件的可读性。这是我所拥有的:

def read_permissions(filepath):
    '''Checks the read permissions of the specified file'''
    try:
        os.access(filepath, os.R_OK) # Find the permissions using os.access
    except IOError:
        return False

    return True

这有效并在运行时返回 True 或 False 作为输出。但是,我希望来自errno 的错误消息伴随它。这是我认为我必须做的(但我知道有什么问题):

def read_permissions(filepath):
    '''Checks the read permissions of the specified file'''
    try:
        os.access(filepath, os.R_OK) # Find the permissions using os.access
    except IOError as e:
        print(os.strerror(e)) # Print the error message from errno as a string

    print("File exists.")

但是,如果我输入一个不存在的文件,它会告诉我该文件存在。有人可以帮助我了解我做错了什么(以及将来我可以做些什么来远离这个问题)?我还没有看到有人使用os.access 尝试过这个。我也愿意接受其他选项来测试文件的权限。有人可以帮助我在出现问题时如何提出适当的错误消息吗?

此外,这可能适用于我的其他功能(他们在检查其他内容时仍然使用os.access,例如使用os.F_OK 的文件的存在和使用os.W_OK 的文件的写权限)。这是我试图模拟的那种事情的一个例子:

>>> read_permissions("located-in-restricted-directory.txt") # Because of a permission error (perhaps due to the directory)
[errno 13] Permission Denied
>>> read_permissions("does-not-exist.txt") # File does not exist
[errno 2] No such file or directory

这是我试图通过向问题返回适当的错误消息来模拟的事情。我希望这将有助于避免对我的问题造成任何混淆。

我应该指出,虽然我已经阅读了os.access 文档,但我并不想稍后再打开该文件。我只是想创建一个模块,其中一些组件用于检查特定文件的权限。我有一个基线(我提到的第一段代码),它充当我其余代码的决策者。在这里,我只是想以一种用户友好的方式重新编写它(不仅仅是True 或只是False,而是使用完整的消息)。由于IOError 可以通过几种不同的方式提出(例如权限被拒绝或不存在的目录),我试图让我的模块识别和发布问题。我希望这可以帮助您帮助我确定任何可能的解决方案。

【问题讨论】:

else 块之后的except 块中尝试使用print("File exists.")。这就是你要找的那种行为吗? 尝试使用return 而不是print 我刚试过(意思是 AirThomas 的建议)。它给了我相同的输出,说文件存在但实际上不存在。我将print("File exists.") 放在else 块中except 块之后。另外,mc10,我只是用print 替换了return,它似乎也没有做任何事情。 Checking File Permissions in Linux with Python、How can I get a file's permission mask?、Checking permission of a file using python、Check the permissions of a file in python 等可能重复 【参考方案1】:

os.access 在文件不存在时返回False,无论传递的模式参数如何。

这在the documentation for os.access 中没有明确说明,但这并不是非常令人震惊的行为;毕竟,如果一个文件不存在,你就不可能访问它。按照文档的建议检查the access(2) man page 提供了另一个线索,因为access 在各种条件下返回-1。无论如何,您可以像我一样简单地在 IDLE 中检查返回值:

>>> import os
>>> os.access('does_not_exist.txt', os.R_OK)
False

在 Python 中,通常不鼓励在尝试实际做有用的事情之前检查类型等。这种哲学通常用首字母缩写词 EAFP 来表达,它代表 Easier to Ask Forgiveness than Permission。如果您再次参考文档,您会发现这与当前案例特别相关:

注意:使用access() 来检查用户是否被授权,例如在实际使用 open() 之前打开文件会创建安全性 漏洞,因为用户可能会利用 检查并打开文件以对其进行操作。最好使用 EAFP 技术。例如:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

最好写成:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

如果除了在调用open() 之前对用户进行二次猜测之外,您还有其他原因检查权限,您可以向How do I check whether a file exists using Python? 寻求一些建议。请记住,如果您确实需要引发异常,您可以随时 raise 自己处理;无需去野外寻找。


由于 IOError 可以通过几种不同的方式出现(例如 权限被拒绝或不存在的目录),我正在尝试获取我的 模块来识别和发布问题。

这就是上面第二种方法的作用。见:

>>> try:
...     open('file_no_existy.gif')
... except IOError as e:
...     pass
...
>>> e.args
(2, 'No such file or directory')
>>> try:
...     open('unreadable.txt')
... except IOError as e:
...     pass
...
>>> e.args
(13, 'Permission denied')
>>> e.args == (e.errno, e.strerror)
True

但是您需要选择一种方法。如果您请求宽恕,请在 try-except 块中执行该操作(打开文件)并适当处理后果。如果你成功了,那么你就知道你成功了,因为没有例外。

另一方面,如果您以这种方式和其他方式请求许可(又名 LBYL,Look Before You Leap),您仍然不知道是否您可以成功打开文件,直到您真正执行它。如果在您检查其权限后文件被移动了怎么办?如果有您没想过要检查的问题怎么办?

如果你还想请求权限,不要使用try-except;你没有做这件事,所以你不会抛出错误。相反,使用条件语句调用os.access 作为条件。

【讨论】:

在您的最后一个示例中,使用IOError 非常广泛。您也可以分别捕获FileNotFoundErrorPermissionError

以上是关于在python中检查文件的权限的主要内容,如果未能解决你的问题,请参考以下文章

Python:检查文件被锁定

在创建文件夹之前检查 VBA Access 中目录的权限

在 C / *nix 中检查指定用户的文件访问权限

在目录中创建文件之前检查目录中的写访问权限

python打包成可执行文件

python异常整理