Python中确定目录是否对执行脚本的用户可写的最佳方式是什么?由于这可能涉及使用os模块,我应该提到我正在* nix环境下运行它。确定目录是否可写
确定目录是否可写
回答
它可能看起来很奇怪表明这一点,但一个共同的Python的成语是
它更容易请求原谅 比许可
继习语,人们可能会说:
尝试写入有问题的目录,并在没有权限的情况下捕获错误。
检查模式位:
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)
)
此解决方案仅适用于Unix。 – 2013-09-26 15:00:07
虽然什么克里斯托夫认为是更Python的解决方案,操作系统模块确实有the os.access function检查访问:
os.access('/path/to/folder', os.W_OK)
#W_OK是写作,R_OK阅读等
根据情况,“容易请求原谅”并不是最好的方式,即使在Python中也是如此。有时候可以像上面提到的os.access()方法那样“询问权限”,例如当发生错误的概率很高时。 – mjv 2010-02-06 19:32:57
如果要将文件写入目录,仅测试写入位是不够的。如果要写入目录,则还需要测试执行位。 os.access('/ path/to/folder',os.W_OK | os.X_OK)os.W_OK本身只能删除目录(只有当该目录为空时) – fthinker 2012-03-23 17:13:14
os.access的另一个问题()'是否使用* real * UID和GID进行检查,而不是* *有效*进行检查。这可能会导致SUID/SGID环境中的怪异现象。 ('但脚本运行setuid root,为什么不能写入文件?') – Alexios 2016-05-13 08:37:28
如果你只关心文件权限,os.access(path, os.W_OK)
应该做你所要求的。如果您想知道您是否可以可以写入目录open()
用于写入的测试文件(它不应该事先存在),请捕获并检查任何IOError
,然后清理测试文件。
更一般地说,为了避免TOCTOU攻击(如果脚本以提升的权限运行 - suid或cgi等),您不应该真正相信这些提前测试,但可以删除priv,do open()
,并期望IOError
。
这里是我创建基于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"
跨越这个线程搜索某人的例子绊倒了。在Google上的第一个结果,恭喜!
人们谈论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")
这种尝试打开用于写入的文件句柄,并以一个错误退出,如果指定的文件无法写入:这是更容易阅读,是一个更好的方式,而不是在文件路径或目录上进行预先检查,因为它避免了竞争条件;在运行预选检查时间以及实际尝试写入文件时,文件变得不可写入的情况。
这适用于文件,而不是OP所要求的目录。您可以在目录中拥有一个文件,并且该目录不可写,但文件本身(如果该文件已存在)。这对于系统管理很重要,例如,您可以创建想要存在的日志文件,但不希望人们将日志目录用于临时空间。 – 2017-04-11 18:41:41
......实际上我把它投下来了,我现在认为这是一个错误。正如Rohaq所提到的,有些问题与竞赛条件有关。在可以测试目录的各种平台上还有其他问题,它看起来是可写的,但实际上并不是这样。执行跨平台目录可写检查比看起来更难。所以只要你意识到这些问题,这可能是一个很好的技术。我从UNIX-Y的角度来看待它,这是我的错误。有人编辑这个答案,所以我可以删除我的-1。 – 2017-04-12 15:29:01
我编辑它,以防你想删除-1 :) 是的,跨平台目录检查可能会变得更加复杂,但通常你正在寻找创建/写入该目录中的文件 - 在这种情况下,我给出的示例仍然适用。如果出现一些与目录权限相关的问题,它在尝试打开文件句柄时仍应该抛出IOError。 – Rohaq 2017-04-22 04:13:44
使用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
我认为使用tempfile的人更清洁,因为它肯定不会留下残留物。 – grasshopper 2014-12-31 00:59:06
此方法不能使用'tempfile'。它只在没有'OSError'意味着它有写/删除权限时才起作用。否则它不会返回False,因为没有返回错误,并且脚本不会继续执行或退出。什么都没有返回。它只是停留在那条线上。然而,创建非临时文件(如khattam的答案)在允许或拒绝权限时都有效。帮帮我? – 2016-05-06 18:24:27
if os.access(path_to_folder, os.W_OK) is not True:
print("Folder not writable")
else :
print("Folder writable")
有关访问的详细信息,可以发现它here
这基本上是一个Max Shawabkeh的答案和一个小包装的副本。使其成为快速复制粘贴,但更好的主意是将其添加到Max的原始帖子。 – 2017-08-20 18:21:52
如果您需要检查的另一个用户许可(是的,我意识到这个矛盾的问题,但可能会派上用场),你可以通过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
- 1. 如何确定请求的目录是否可写?
- 2. 确定FILE *是否可写
- 3. 如何确定安装目录是否具有写入权限
- 4. 确定目录是否包含文件
- 5. 是否可以确定另一个进程的工作目录?
- 6. 确定两个目录名是否指向同一目录
- 7. 是否可以搜索目录内的特定目录?
- 8. 确定是否点可见
- 9. 确定AJAX是否可能?
- 10. 确定WindowServer是否可用?
- 11. 确定字符串输入是否可以是Python中的有效目录
- 12. 确定NSString中的路径是否是目录或文件?
- 13. 确定FTP URL是否是目录名或使用C#
- 14. 在将root重写到该目录后,是否可以“隐藏”子目录?
- 15. Android可绘制目录是否可以包含子目录?
- 16. Log4J - 确定记录器是否无法写入文件系统
- 17. 检查是否每个人都可以读取/写入目录
- 18. 如何检查是否可以将文件写入目录?
- 19. 如何检查目录是否可以被UID写入?
- 20. 如何检查目录是否可以在PHP中写入?
- 21. 如何使用Delphi来测试目录是否可写?
- 22. ListView ItemDataBound - 确定项目是否是AlternatingItem?
- 23. 确认主目录下的目录是否存在
- 24. 确定是否Any.Type是可选
- 25. 如何确定是否可以写入管道
- 26. 是否有可能确定.NET程序集编写的语言?
- 27. 如何使用JavaScript来确定目录是否存在?
- 28. 确定open()函数是否打开了文件或目录?
- 29. 如何确定一个目录路径是否被隐藏
- 30. 无法确定服务:vora目录是否正在运行
+1 Python或没有,这是真的来测试访问的最可靠方法。 – 2010-01-21 22:32:32
这还处理写入磁盘时可能发生的其他错误 - 例如,没有剩余磁盘空间。这是努力的力量..你不需要记住一切可能出错;-) – 2010-01-21 23:37:57
谢谢你们。由于速度是我在这里做的事情的一个重要因素,所以决定和os.access一起去,尽管我当然可以理解“请求宽恕比容许更容易”的优点。 ;) – illuminatedtiger 2010-01-22 01:04:26