在 Windows 上打开一个目录:“权限被拒绝" [英] Open a directory on Windows: 'Permission denied'

查看:41
本文介绍了在 Windows 上打开一个目录:“权限被拒绝"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取目录的文件描述符,但在目录上调用 os.open 总是会导致权限被拒绝"错误.我不认为这是权限问题,因为它发生在 all 目录上,而文件没有问题(请参阅下面的 REPL 会话).以管理员身份运行没有区别.

Python 2.7.6(默认,2013 年 11 月 10 日,19:24:18)[MSC v.1500 32 位(英特尔)] on win32输入帮助"、版权"、信用"或许可"以获取更多信息.>>>导入操作系统>>>os.mkdir('mydir')>>>os.access('mydir', os.F_OK)真的>>>os.access('mydir', os.R_OK)真的>>>os.access('.', os.R_OK)真的>>>os.access('.', os.F_OK)真的>>>os.open('我的文件', os.O_RDWR)3>>>os.open('mydir', os.O_RDONLY)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中OSError: [Errno 13] 权限被拒绝:'mydir'>>>os.open('mydir', os.O_RDWR)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中OSError: [Errno 13] 权限被拒绝: 'mydir'>>>打开('mydir')回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中IOError: [Errno 13] 权限被拒绝: 'mydir'

在 linux 上它按预期工作:

<预><代码>>>>os.open('mydir', os.O_RDONLY)3

文档并未表明您不能或任何平台差异.这是预期的行为吗?是否无法在 Windows 上获取目录的文件描述符?

解决方案

这不是权限问题,它永远不会与 Python 2 一起使用.Python 2 在执行 os.open() 时正在使用 Win 32 API 调用 _wopen (代码:https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554).根据文档,打开目录时会引发错误:

<块引用>

EACCES试图打开只读文件进行写入,文件的共享模式不允许指定操作,或者给定的路径是目录.

所以:

<块引用>

文档并未表明您不能或任何平台差异.是这是预期的行为?

这是预期的行为.我会说在这种情况下,Python 文档中没有澄清这个细节是好的.

<块引用>

在 Windows 上无法获取目录的文件描述符吗?

在 Python 2 上,您可以使用 ctypes 模块自行调用任意 Win 32 API 方法.Python 3 使用 CreateFile 而不是 _wopen,这是一种更现代的 API 调用,可以让您做您想做的事,见下文.

旧答案:

这个问题最重要的资源是 CreateFile Win 32 API 函数的文档,记录在这里:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

您可能想阅读它的相关部分,例如

<块引用>

要使用 CreateFile 打开目录,请指定FILE_FLAG_BACKUP_SEMANTICS 标志作为 dwFlagsAndAttributes 的一部分.

另外,文档下方有一条评论,说

<块引用>

为了打开一个处理您似乎需要 SYNCHRONIZE 访问的目录,即使您没有请求任何访问权限.(注意:这不适用,如果您有备份/恢复权限.)

Python 3 有好几个地方用到了这个功能,大家可以自己搜索一下

https://github.com/python/cpython/search?q=CreateFile&type=Code

或通过 git clone 并使用 grep -HR "CreateFile(" ..在 Python 3 中,最有可能在执行 os.open() 在 Windows 上.

在 Python 2 上,https 中有对 _wopen 的调用://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554,但我不确定这是在哪里定义的.当您遵循此路径时,您将找到实际的实现.然后您可以看到 Python 是如何调用该函数的——这与文档一起很可能会解释您的观察结果.

I'm trying to get a file descriptor for a directory but calling os.open on on directories always result in a "permission denied" error. I do not believe it's a permission issue because it happens on all directories, while there's no issue on files (See REPL session below). Running as administrator makes no difference.

Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.mkdir('mydir')
>>> os.access('mydir', os.F_OK)
True
>>> os.access('mydir', os.R_OK)
True
>>> os.access('.', os.R_OK)
True
>>> os.access('.', os.F_OK)
True
>>> os.open('myfile', os.O_RDWR)
3
>>> os.open('mydir', os.O_RDONLY)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> os.open('mydir', os.O_RDWR)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> open('mydir')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 13] Permission denied: 'mydir'

On linux it works as expected:

>>> os.open('mydir', os.O_RDONLY)
3

The docs does not indicate you can't nor any platform difference. Is this expected behavior? Is it not possible to get file descriptors for directories on Windows?

解决方案

Edit:

This is not a permission issue, it will never work with Python 2. Python 2 is using the Win 32 API call _wopen when doing os.open() (code: https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554). According to the docs, it throws an error when opening a directory:

EACCES Tried to open read-only file for writing, file's sharing mode does not allow specified operations, or given path is directory.

So:

The docs does not indicate you can't nor any platform difference. Is this expected behavior?

It is expected behavior. I would say in this case it is fine that this detail is not clarified in the Python docs.

Is it not possible to get file descriptors for directories on Windows?

On Python 2 you can use the ctypes module for calling arbitrary Win 32 API methods yourself. Python 3 uses CreateFile instead of _wopen, a more modern API call, which might enable you to do what you want, see below.

Old answer:

The most important resource for this question is the documentation for the CreateFile Win 32 API function, documented here:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

You might want to read the relevant parts of it, e.g.

To open a directory using CreateFile, specify the FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFlagsAndAttributes.

Also, there is a comment below the docs, saying

In order to open a handle to a directory you appear to need SYNCHRONIZE access, even if you aren't requesting any access rights. (Note: this doesn't apply if you have backup/restore privilege.)

Python 3 uses this function in several places, you may want to search for yourself

https://github.com/python/cpython/search?q=CreateFile&type=Code

or via git clone and using grep -HR "CreateFile(" .. In Python 3, there is the _winapi.c module which is most likely used when doing os.open() on Windows.

On Python 2, there is a call to _wopen in https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554, but I am not sure where this is defined. When you follow this path, you will find the actual implementation. Then you can see how exactly Python is calling that function -- this, together with the docs, will most likely explain your observations.

这篇关于在 Windows 上打开一个目录:“权限被拒绝"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆