Answers:
尽管Christophe建议的是更Python化的解决方案,但os模块确实具有os.access函数来检查访问:
os.access('/path/to/folder', os.W_OK)
#W_OK用于写入,R_OK用于读取,等等。
os.access()
是它使用实际的 UID和GID 进行检查,而不是有效的检查。这可能会导致SUID / SGID环境中的异常。(“但是脚本运行setuid root,为什么不能将其写入文件?”)
os.access(dirpath, os.W_OK | os.X_OK)
即使我没有写访问权也返回True。
提出这个建议似乎很奇怪,但是一个常见的Python习惯用法是
寻求宽恕比获得许可要容易
遵循这一习语,人们可能会说:
尝试写入有问题的目录,如果没有权限,则捕获错误。
except: pass
-这样,您可以始终保持乐观并高度评价自己。/讽刺。现在,为什么我要(例如,尝试在文件系统中的每个目录中写入一些内容)以生成可写位置列表?
我使用tempfile
模块的解决方案:
import tempfile
import errno
def isWritable(path):
try:
testfile = tempfile.TemporaryFile(dir = path)
testfile.close()
except OSError as e:
if e.errno == errno.EACCES: # 13
return False
e.filename = path
raise
return True
更新:在Windows上再次测试代码后,我发现在那里使用tempfile确实存在问题,请参见issue22107:tempfile模块错误地解释了Windows上的拒绝访问错误。对于不可写的目录,代码会挂起几秒钟,最后抛出IOError: [Errno 17] No usable temporary file name found
。也许这是user2171842正在观察的内容?不幸的是,该问题暂时无法解决,因此要解决此问题,还必须捕获该错误:
except (OSError, IOError) as e:
if e.errno == errno.EACCES or e.errno == errno.EEXIST: # 13, 17
那时在这些情况下当然仍然存在延迟。
偶然发现该线程在寻找某人的示例。恭喜,您在Google上获得了第一个结果!
人们谈论在此线程中使用Python的方式,但是没有简单的代码示例吗?在这里,对于任何偶然发现的人:
import sys
filepath = 'C:\\path\\to\\your\\file.txt'
try:
filehandle = open( filepath, 'w' )
except IOError:
sys.exit( 'Unable to write to file ' + filepath )
filehandle.write("I am writing this text to the file\n")
这会尝试打开文件句柄进行写入,如果指定的文件无法写入,则会退出并返回错误:这更容易阅读,并且比对文件路径或目录进行预检查要好得多,因为它避免了比赛条件;在运行预检查的时间到实际尝试写入文件之间文件不可写的情况。
这是我根据ChristopheD的答案创建的:
import os
def isWritable(directory):
try:
tmp_prefix = "write_tester";
count = 0
filename = os.path.join(directory, tmp_prefix)
while(os.path.exists(filename)):
filename = "{}.{}".format(os.path.join(directory, tmp_prefix),count)
count = count + 1
f = open(filename,"w")
f.close()
os.remove(filename)
return True
except Exception as e:
#print "{}".format(e)
return False
directory = "c:\\"
if (isWritable(directory)):
print "directory is writable"
else:
print "directory is not writable"
if os.access(path_to_folder, os.W_OK) is not True:
print("Folder not writable")
else :
print("Folder writable")
有关访问的更多信息可以在这里找到
通过argparse添加参数时,我遇到了同样的需求。内置type=FileType('w')
目录对我不起作用,因为我在寻找目录。我最终写出了自己的方法来解决我的问题。这是argparse代码段的结果。
#! /usr/bin/env python
import os
import argparse
def writable_dir(dir):
if os.access(dir, os.W_OK) and os.path.isdir(dir):
return os.path.abspath(dir)
else:
raise argparse.ArgumentTypeError(dir + " is not writable or does not exist.")
parser = argparse.ArgumentParser()
parser.add_argument("-d","--dir", type=writable_dir(), default='/tmp/',
help="Directory to use. Default: /tmp")
opts = parser.parse_args()
结果如下:
$ python dir-test.py -h
usage: dir-test.py [-h] [-d DIR]
optional arguments:
-h, --help show this help message and exit
-d DIR, --dir DIR Directory to use. Default: /tmp
$ python dir-test.py -d /not/real
usage: dir-test.py [-h] [-d DIR]
dir-test.py: error: argument -d/--dir: /not/real is not writable or does not exist.
$ python dir-test.py -d ~
我回过头来,在最后添加了print opts.dir,一切似乎都可以正常运行了。
如果您需要检查其他用户的权限(是的,我知道这与问题相矛盾,但可能对某人有用),则可以通过pwd
模块和目录的模式位来进行检查。
免责声明 -在Windows上不起作用,因为它不使用POSIX权限模型(并且该pwd
模块在那里不可用),例如-仅针对* nix系统的解决方案。
请注意,目录必须设置所有3位-读,写和eXecute。
好的,R不是绝对必须的,但是没有,您不能在目录中列出条目(因此您必须知道它们的名称)。另一方面,绝对需要执行-没有用户无法读取文件的inode;因此即使没有W也无法创建或修改W。在此链接上有更详细的说明。
最后,这些模式在stat
模块中可用,其描述在inode(7)man中。
示例代码如何检查:
import pwd
import stat
import os
def check_user_dir(user, directory):
dir_stat = os.stat(directory)
user_id, group_id = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid
directory_mode = dir_stat[stat.ST_MODE]
# use directory_mode as mask
if user_id == dir_stat[stat.ST_UID] and stat.S_IRWXU & directory_mode == stat.S_IRWXU: # owner and has RWX
return True
elif group_id == dir_stat[stat.ST_GID] and stat.S_IRWXG & directory_mode == stat.S_IRWXG: # in group & it has RWX
return True
elif stat.S_IRWXO & directory_mode == stat.S_IRWXO: # everyone has RWX
return True
# no permissions
return False