为什么一个文件可写,但使用os.access( file, os.W_OK )返回false?

3

我不太确定这里发生了什么。根据Python的解释:

> os.W_OK: mode参数的值之一,用于access()函数以测试路径的写入权限。

我猜想这个检查应该返回True,即使文件并不存在,但它的路径是有效的,并且我有权限写入此文件。

但是当我尝试检查文件路径是否可写时会发生什么呢?

import os, subprocess
pwd = os.getcwd();
temp_file_to_write = os.path.join( pwd, "temp_file" );
# use os.access to check 
say = "";
if ( os.access( temp_file_to_write, os.W_OK ) ) :
    say = "writeable";
else :
    say = "NOT writeable";

print "L10", temp_file_to_write, "is", say
# use try/except
try :
    with open( temp_file_to_write, "w" ) as F :
        F.write( "L14 I am a temp file which is said " + say + "\n" );
    print "L15", temp_file_to_write, "is written";
    print subprocess.check_output( ['cat', temp_file_to_write ] );
except Exception, e:
    print "L18", temp_file_to_write, "is NOT writeable";

它会产生以下结果。
L10 /home/rex/python_code/sandbox/temp_file is NOT writeable
L15 /home/rex/python_code/sandbox/temp_file is written
L14 I am a temp file which is said NOT writeable

有人知道为什么吗?如果我对 os.W_OK 的理解是错误的,你能告诉我在 Python 中检查以下两个条件的正确方法吗:1)文件路径是否有效;2)我是否具有写入权限。

3个回答

2

能否创建新文件取决于目录的权限,而不是新的不存在(但即将创建)的文件。

一旦文件被创建(存在),如果您可以修改其内容,则access(W_OK)可能会返回true。


是的,在我创建了那个文件之后,os.access(file, W_OK)返回True。但是,在Python中是否有可能在实际写入文件并捕获异常之前检查文件是否可写? - pitfall
@user36624:在你创建文件之前,没有什么可以检查的。正如我在答案中所说的:你可以检查目录——无论你是否被允许在其中创建文件(如果设置了wx,则允许在其中创建文件)。 - jfs

0
也许你是用sudo(或者在Windows上类似的东西)来运行你的脚本的? 我在Linux上这样做了(我给了chmod 400):
>>> os.access(fn, os.W_OK)
False
>>> f = open(fn, 'w')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 13] Permission denied: '/tmp/non-writable'

0

原始问题是如何检查写入文件的权限。然而,在Python中,当可能时,最好使用try-except块尝试写入文件,而不是测试访问权限。这个原因在Python.org网站上的os.access()文档中给出:https://docs.python.org/3/library/os.html

来自该网站的说明:

注意:在使用open()实际打开文件之前,使用access()检查用户是否有权打开文件会创建安全漏洞,因为用户可能利用检查和打开文件之间的短时间间隔来操纵它。最好使用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 PermissionError:
    return "some default data"
else:
    with fp:
        return fp.read()

注意:即使access()表明它们将成功,I / O操作也可能失败,特别是对于在网络文件系统上执行的操作,这些操作可能具有超出通常的POSIX权限位模型的权限语义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接