在Python中确定目录对于执行脚本的用户是否可写的最佳方法是什么?由于这可能涉及使用os模块,我应该提到我在* nix环境下运行它。
答案 0 :(得分:154)
尽管Christophe建议使用更多Pythonic解决方案,但os模块确实有the os.access function来检查访问权限:
os.access('/path/to/folder', os.W_OK)
#W_OK用于写作,R_OK用于阅读等。
答案 1 :(得分:63)
建议这一点似乎很奇怪,但是常见的Python习语是
要求宽恕更容易 而非许可
遵循这个习语,有人会说:
尝试写入相关目录,如果您没有权限,请抓住错误。
答案 2 :(得分:15)
我的解决方案使用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
答案 3 :(得分:10)
偶然发现这个线程正在寻找某人的例子。第一个结果在谷歌,恭喜!
人们在这个帖子中谈论Pythonic的做法,但没有简单的代码示例?在这里,你去找其他任何偶然发现的人:
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")
这会尝试打开文件句柄进行写入,如果指定的文件无法写入,则会退出并显示错误:这更容易阅读,并且是一种更好的方法,而不是在文件路径上执行预先检查或者目录,因为它避免了竞争条件;在运行预检和实际尝试写入文件之间文件变为不可写的情况。
答案 4 :(得分:9)
如果您只关心文件权限,os.access(path, os.W_OK)
应该按照您的要求进行操作。如果你想知道你是否可以写入目录,open()
一个用于写入的测试文件(它不应该事先存在),捕获并检查任何IOError
,然后清理测试文件。
更一般地说,为了避免TOCTOU攻击(如果你的脚本以提升的权限运行,只有一个问题 - suid或cgi左右),你不应该真正信任这些提前测试,而是放弃privs,执行open()
,并期待IOError
。
答案 5 :(得分:7)
检查模式位:
def isWritable(name):
uid = os.geteuid()
gid = os.getegid()
s = os.stat(dirname)
mode = s[stat.ST_MODE]
return (
((s[stat.ST_UID] == uid) and (mode & stat.S_IWUSR)) or
((s[stat.ST_GID] == gid) and (mode & stat.S_IWGRP)) or
(mode & stat.S_IWOTH)
)
答案 6 :(得分:4)
这是我根据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"
答案 7 :(得分:3)
if os.access(path_to_folder, os.W_OK) is not True:
print("Folder not writable")
else :
print("Folder writable")
有关访问权限的更多信息可以找到它here
答案 8 :(得分:1)
我在通过argparse添加参数时遇到了同样的需求。当我在寻找目录时,内置的Dialog
对我不起作用。我最终写出了自己的方法来解决我的问题。这是带有argparse代码段的结果。
type=FileType('w')
结果如下:
#! /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()
我回过头来,在最后添加了 print opts.dir ,一切似乎都可以正常运行。
答案 9 :(得分:0)
如果您需要检查其他用户的权限(是的,我发现这与此问题相矛盾,但可能会对某人有用),您可以通过pwd
进行操作模块和目录的模式位。
免责声明 - 在Windows上不起作用,因为它不使用POSIX权限模型(并且pwd
模块在那里不可用),例如 - 仅适用于* nix系统的解决方案。
请注意,目录必须设置所有3位 - 读取,写入和执行 好吧,R不是绝对必须的,但是如果不能列出目录中的条目(那么你必须知道它们的名字)。另一方面,执行是绝对必要的 - 用户无法读取文件的inode;所以即使有W,也没有X文件无法创建或修改。 More detailed explanation at this link.
最后,这些模式在stat
模块中可用,descriptions are in 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