【发布时间】:2019-05-27 13:11:49
【问题描述】:
我有一个只读文件,比如 samp.txt,我在 PowerShell 上运行以下命令:
> $file = Get-Item .\samp.txt
> $file.LastAccessTime = (get-date)
我们得到:"Access to the path 'G:\Study_Material\Coding\samp.txt' is denied."
在我们继续之前,先看看访问时间:
> $file.LastAccessTime 会是
Sunday, December 30, 2018 11:02:49 PM
现在我们打开 WSL 并执行:$ touch samp.txt
回到我们做的 PowerShell:
> $file = Get-Item .\samp.txt
> $file.LastAccessTime
我们得到:
Sunday, December 30, 2018 11:19:16 PM
因此它已被修改,没有提升权限。
现在我的问题是:如何在不通过修改 $file.Attributes 删除 ReadOnly 标记的情况下单独在 PowerShell 中模拟此操作。
【问题讨论】:
-
只读属性保护文件数据,而不是元数据。它不应阻止使用
FILE_WRITE_ATTRIBUTES访问权限打开文件或导致SetFileTime失败。 Python 的os.utime在 Windows 上调用后一个函数,它适用于只读文件。我将在此处研究 PowerShell 失败的原因。 -
这是一个 .NET 错误。
System.IO.File.SetLastAccessTimeUtc的实现尝试以GENERIC_WRITE访问权限打开文件,这超出了要求,并且对于只读文件失败。 -
感谢您的回复。那么touch命令或者os.utime是不是以不同的方式打开文件呢?
-
Python 的
os.utime请求写入属性访问。这是对CreateFile始终请求的最低要求的补充:读取属性和同步访问。相比之下,通用写入访问包括写入数据和附加数据访问,这对于只读文件是不允许的。 -
Linux
touch基于utimensat。起初touch尝试获得写访问权限,但由于只读属性(在 WSL 中映射为没有写权限,但它应该映射到具有 NTFS 语义的“不可变”属性),它不能。它仍然可以在没有启用写入的 fd 的情况下成功,因为时间只是当前的并且调用者是所有者。当 WSL 在“/mnt”下挂载卷时,WSL 使用 Windows 会话用户作为所有文件的所有者,因此这本身是不够的。它必须进行另一次 NT 访问检查以确定用户是否具有所需的写入属性访问权限。
标签: windows powershell windows-subsystem-for-linux