Windows 上的 Python 3.5 - 覆盖其他用户创建的文件“PermissionError:[Errno 13]”

Posted

技术标签:

【中文标题】Windows 上的 Python 3.5 - 覆盖其他用户创建的文件“PermissionError:[Errno 13]”【英文标题】:Python 3.5 on Windows - Overwriting files created by other users "PermissionError: [Errno 13]" 【发布时间】:2015-12-20 16:45:57 【问题描述】:

我正在编写一个 python 脚本来获取一个文件,根据第一个文件对其进行更改以生成多个新文件。这个想法是,如果第一个文件被更新,我或我的其他同事可以在我们的服务器上运行脚本(运行 Windows Server 2008 r2)并将更改传播到其他文件。

但是,当涉及到 Windows 文件权限时,我们遇到了障碍。

当脚本创建文件时,它会创建具有以下权限的文件:

运行脚本的用户:完全控制、读取、读取和执行、修改、写入 管理员组:完全控制、读取、读取和执行、修改、写入 系统:完全控制、读取、读取和执行、修改、写入 用户组:读取、读取和执行

我观察到以下行为:

当我或我的老板运行脚本并且不存在任何子文件时,脚本运行良好并创建新文件。 当我或我的老板运行脚本时,子文件存在并且是由运行脚本的同一个人先前运行创建的,脚本运行良好并覆盖现有文件。 当我运行脚本时,子文件存在但由运行脚本的老板创建,脚本失败并显示 `PermissionError: [Errno 13] Permission denied。 当我的老板运行脚本时,子文件存在但由我运行脚本创建,脚本失败并显示 `PermissionError: [Errno 13] Permission denied。

根据控制面板中的用户列表,我和我的老板都是管理员,所以根据权限应该没有问题,但我们仍然得到错误。

我做错了什么?

有没有办法改变脚本的文件权限,或者在脚本写入之前删除文件?

代码如下:

#All variables are set above
#They have no bearing on file permissions other than setting the paths to read/write
fileIn = io.open(filePath, mode='r')
print ("Reading " + filePath)
for line in fileIn:
    for x in range(0,5):
        contentsOut[x] += line
        if line[:len(seekLine)] == seekLine:
            contentsOut[x] += catSection.format(catStrings[x])
            print ("written category string")
fileIn.close()
for x in range(0,5):
    fileOutName = basePath + fileFormat.format(catStrings[x])
    fileOut = io.open(fileOutName, mode='wt', encoding='utf_8',newline='\r\n')
    print ("Writing " + fileOutName)
    fileOut.write(contentsOut[x])
    fileOut.close()
    print ("Write finished")

编辑: 从那以后,我更改了算法以在写入之前删除文件,它给出了更奇怪的结果。

由于某种原因,如果存在的文件是我创建的,我的老板无法通过运行脚本来删除它们,并且当他点击os.remove(fileOutName) 行时会得到PermissionError: [WinError 5] Access is denied

但是我没有任何问题,并且无论是我还是我的老板创建文件都可以正常运行脚本。

在我寻找解决方案之前,我真的需要知道为什么会发生这种情况。 从那以后我还被告知只有管理员才能执行此操作,因此当前的文件权限看起来不错,前提是它们没有碍事。

fileIn = io.open(filePath, mode='r')
print ("Reading " + filePath)
for line in fileIn:
    for x in range(0,noOfOutFiles):
        contentsOut[x] += line
        if line[:len(seekLine)] == seekLine:
            contentsOut[x] += catSection.format(catStrings[x])
            print ("written category string")
fileIn.close()
for x in range(0,noOfOutFiles):
    fileOutName = basePath + '\\' + scopePath + '\\' + typePath + '\\' + fileFormat.format(catStrings[x])
    if os.path.exists(fileOutName):
        print ("Deleting " + fileOutName)
        os.remove(fileOutName)
    print ("Writing " + fileOutName)
    fileOut = io.open(fileOutName, mode='wt', encoding='utf_8',newline='\r\n')
    fileOut.write(contentsOut[x])
    fileOut.close()
    print ("Write finished")

编辑:我在 '.' 上运行 icacls (当前目录)和生成的文件之一,结果如下:

当前目录:

NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
SERVERNAME\Me:(I)(F)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)

文件:

NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
SERVERNAME\Me:(I)(F)

我的老板并没有被特别列出,但我是,这很奇怪,我们都不记得添加了那个权限。

【问题讨论】:

如果启用了 UAC,那么您的管理员令牌会分成两部分,一个是受限制的,另一个是不受限制的。不受限制的令牌也称为“提升”令牌,因为它具有“高”强制性完整性级别。检查whoami /groups /fo list。如果命令提示符不是“以管理员身份运行”,那么您应该看到 BUILTIN\Administrators 设置为“仅用于拒绝的组”。这意味着授予管理员访问权限的安全描述符 DACL 中的 ACE 不适用于您的非提升令牌。 请注意,目录可以授予FILE_DELETE_CHILD File Access Right,这隐含地允许拥有此权限的用户删除文件和子目录。看来您对相关目录具有此权限,但您的老板没有。检查icacls dirpath 以列出目录的 DACL 中的 ACE。 @eryksun 事情是我的老板可以手动删除 tehm,方法是进入资源管理器并点击删除。只是脚本在他运行时无法删除。 @eryksun 添加了 icacls 的结果,很奇怪 您是否创建了目录? dir /q 显示所有者。 CREATOR OWNER 有一个继承的 ACE,它授予文件(对象继承)和目录(容器继承)的创建者完全控制权。由于您拥有目录的完全控制权,因此您可以删除老板创建的文件。对于资源管理器,它提升管理员删除文件,但应该有一个提示要求管理员权限。 【参考方案1】:

如果您使用 win32security 模型,您将可以完全控制为不同组设置文件权限。

http://timgolden.me.uk/python/win32_how_do_i/add-security-to-a-file.html

dacl = win32security.ACL ()
dacl.AddAccessAllowedAce (win32security.ACL_REVISION, con.FILE_GENERIC_READ, everyone)
dacl.AddAccessAllowedAce (win32security.ACL_REVISION, con.FILE_GENERIC_READ | con.FILE_GENERIC_WRITE, user)
dacl.AddAccessAllowedAce (win32security.ACL_REVISION, con.FILE_ALL_ACCESS, admins)

【讨论】:

但是您知道为什么会发生这种情况吗?因为不管权限如何,这种行为似乎很奇怪。 创建文件所在文件夹的权限是什么?据我所知,在 Windows 中,它继承了父文件夹的权限。你可能想检查一下。

以上是关于Windows 上的 Python 3.5 - 覆盖其他用户创建的文件“PermissionError:[Errno 13]”的主要内容,如果未能解决你的问题,请参考以下文章

在 32 位 Windows 7 机器上使用 Python 3.5 安装 scipy

在python 3.5中安装senticnet

你如何用 Mingw 编译 python 3.5 代码?

将 linux 2.7 上的 python 更新到 3.5

Windows10 python 3.5 Scrapy 安装配置

python 在Python 3.5上的Mac OS Sierra上安装OpenCV