确定目录是否可写。

时间:2021-01-17 04:30:12

What would be the best way in Python to determine whether a directory is writeable for the user executing the script? Since this will likely involve using the os module I should mention I'm running it under a *nix environment.

Python中最好的方法是确定一个目录是否可以为执行脚本的用户编写?因为这可能涉及到使用os模块,我应该提到我在一个*nix环境下运行它。

9 个解决方案

#1


130  

Although what Christophe suggested is a more Pythonic solution, the os module does have the os.access function to check access:

虽然Christophe建议的是一个更python化的解决方案,但是os模块确实有操作系统。访问函数检查访问权限:

os.access('/path/to/folder', os.W_OK) # W_OK is for writing, R_OK for reading, etc.

操作系统。访问('/path/to/文件夹',os.W_OK) # W_OK是用于写入,R_OK用于读取,等等。

#2


57  

It may seem strange to suggest this, but a common Python idiom is

这似乎很奇怪,但是一个常见的Python习语是。

It's easier to ask for forgiveness than for permission

请求原谅比请求允许更容易。

Following that idiom, one might say:

按照这个成语,人们可能会说:

Try writing to the directory in question, and catch the error if you don't have the permission to do so.

试着在问题目录中写入,如果没有权限,就可以捕获错误。

#3


15  

My solution using the tempfile module:

我的解决方案使用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

#4


9  

If you only care about the file perms, os.access(path, os.W_OK) should do what you ask for. If you instead want to know whether you can write to the directory, open() a test file for writing (it shouldn't exist beforehand), catch and examine any IOError, and clean up the test file afterwards.

如果您只关心文件perms,操作系统。access(path, os.W_OK)应该按照你的要求去做。如果您想知道您是否可以写入目录,打开()一个测试文件(它不应该预先存在),捕获和检查任何IOError,然后清理测试文件。

More generally, to avoid TOCTOU attacks (only a problem if your script runs with elevated privileges -- suid or cgi or so), you shouldn't really trust these ahead-of-time tests, but drop privs, do the open(), and expect the IOError.

更一般的情况是,为了避免TOCTOU攻击(如果您的脚本运行具有更高的特权——suid或cgi),您就不应该真正相信这些提前测试,但是放弃privs,执行open(),并期望IOError。

#5


9  

Stumbled across this thread searching for examples for someone. First result on Google, congrats!

无意中发现了这条线,寻找某人的例子。第一个结果是谷歌,恭喜!

People talk about the Pythonic way of doing it in this thread, but no simple code examples? Here you go, for anyone else who stumbles in:

人们谈论在这个线程中执行它的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")

This attempts to open a filehandle for writing, and exits with an error if the file specified cannot be written to: This is far easier to read, and is a much better way of doing it rather than doing prechecks on the file path or the directory, as it avoids race conditions; cases where the file becomes unwriteable between the time you run the precheck, and when you actually attempt to write to the file.

这对写作试图打开一个文件句柄,并退出错误如果不能写入指定的文件:这是更容易阅读,和是一个更好的方法而不是做预检验文件路径或目录,因为它避免竞态条件;当您运行precheck的时候,当您实际尝试写入文件时,文件变得不可写。

#6


7  

Check the mode bits:

检查方式:

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)
     )

#7


4  

Here is something I created based on ChristopheD's answer:

这是我根据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"

#8


2  

 if os.access(path_to_folder, os.W_OK) is not True:
            print("Folder not writable")
 else :
            print("Folder writable")

more info about access can be find it here

关于访问的更多信息可以在这里找到。

#9


0  

If you need to check the permission of another user (yes, I realize this contradicts the question, but may come in handy for someone), you can do it through the pwd module, and the directory's mode bits.

如果您需要检查其他用户的权限(是的,我意识到这与问题相矛盾,但是可能对某人来说很方便),您可以通过pwd模块和目录的模式位来完成。

Disclaimer - does not work on Windows, as it doesn't use the POSIX permissions model (and the pwd module is not available there), e.g. - solution only for *nix systems.

免责声明-不适用于Windows,因为它不使用POSIX权限模型(以及pwd模块在那里不可用),例如,仅用于*nix系统的解决方案。

Note that a directory has to have all the 3 bits set - Read, Write and eXecute.
Ok, R is not an absolute must, but w/o it you cannot list the entries in the directory (so you have to know their names). Execute on the other hand is absolutely needed - w/o it the user cannot read the file's inodes; so even having W, without X files cannot be created or modified. More detailed explanation at this link.

注意,目录必须具有所有的3位集——读、写和执行。好的,R不是绝对必须的,但是w/o你不能列出目录中的条目(所以你必须知道它们的名字)。另一方面执行是绝对需要的- w/o,用户无法读取文件的inode;所以即使有W,没有X文件也不能创建或修改。更详细的解释在此链接。

Finally, the modes are available in the stat module, their descriptions are in inode(7) man.

最后,这些模式在stat模块中是可用的,它们的描述在inode(7)中。

Sample code how to check:

样本代码如何检查:

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


130  

Although what Christophe suggested is a more Pythonic solution, the os module does have the os.access function to check access:

虽然Christophe建议的是一个更python化的解决方案,但是os模块确实有操作系统。访问函数检查访问权限:

os.access('/path/to/folder', os.W_OK) # W_OK is for writing, R_OK for reading, etc.

操作系统。访问('/path/to/文件夹',os.W_OK) # W_OK是用于写入,R_OK用于读取,等等。

#2


57  

It may seem strange to suggest this, but a common Python idiom is

这似乎很奇怪,但是一个常见的Python习语是。

It's easier to ask for forgiveness than for permission

请求原谅比请求允许更容易。

Following that idiom, one might say:

按照这个成语,人们可能会说:

Try writing to the directory in question, and catch the error if you don't have the permission to do so.

试着在问题目录中写入,如果没有权限,就可以捕获错误。

#3


15  

My solution using the tempfile module:

我的解决方案使用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

#4


9  

If you only care about the file perms, os.access(path, os.W_OK) should do what you ask for. If you instead want to know whether you can write to the directory, open() a test file for writing (it shouldn't exist beforehand), catch and examine any IOError, and clean up the test file afterwards.

如果您只关心文件perms,操作系统。access(path, os.W_OK)应该按照你的要求去做。如果您想知道您是否可以写入目录,打开()一个测试文件(它不应该预先存在),捕获和检查任何IOError,然后清理测试文件。

More generally, to avoid TOCTOU attacks (only a problem if your script runs with elevated privileges -- suid or cgi or so), you shouldn't really trust these ahead-of-time tests, but drop privs, do the open(), and expect the IOError.

更一般的情况是,为了避免TOCTOU攻击(如果您的脚本运行具有更高的特权——suid或cgi),您就不应该真正相信这些提前测试,但是放弃privs,执行open(),并期望IOError。

#5


9  

Stumbled across this thread searching for examples for someone. First result on Google, congrats!

无意中发现了这条线,寻找某人的例子。第一个结果是谷歌,恭喜!

People talk about the Pythonic way of doing it in this thread, but no simple code examples? Here you go, for anyone else who stumbles in:

人们谈论在这个线程中执行它的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")

This attempts to open a filehandle for writing, and exits with an error if the file specified cannot be written to: This is far easier to read, and is a much better way of doing it rather than doing prechecks on the file path or the directory, as it avoids race conditions; cases where the file becomes unwriteable between the time you run the precheck, and when you actually attempt to write to the file.

这对写作试图打开一个文件句柄,并退出错误如果不能写入指定的文件:这是更容易阅读,和是一个更好的方法而不是做预检验文件路径或目录,因为它避免竞态条件;当您运行precheck的时候,当您实际尝试写入文件时,文件变得不可写。

#6


7  

Check the mode bits:

检查方式:

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)
     )

#7


4  

Here is something I created based on ChristopheD's answer:

这是我根据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"

#8


2  

 if os.access(path_to_folder, os.W_OK) is not True:
            print("Folder not writable")
 else :
            print("Folder writable")

more info about access can be find it here

关于访问的更多信息可以在这里找到。

#9


0  

If you need to check the permission of another user (yes, I realize this contradicts the question, but may come in handy for someone), you can do it through the pwd module, and the directory's mode bits.

如果您需要检查其他用户的权限(是的,我意识到这与问题相矛盾,但是可能对某人来说很方便),您可以通过pwd模块和目录的模式位来完成。

Disclaimer - does not work on Windows, as it doesn't use the POSIX permissions model (and the pwd module is not available there), e.g. - solution only for *nix systems.

免责声明-不适用于Windows,因为它不使用POSIX权限模型(以及pwd模块在那里不可用),例如,仅用于*nix系统的解决方案。

Note that a directory has to have all the 3 bits set - Read, Write and eXecute.
Ok, R is not an absolute must, but w/o it you cannot list the entries in the directory (so you have to know their names). Execute on the other hand is absolutely needed - w/o it the user cannot read the file's inodes; so even having W, without X files cannot be created or modified. More detailed explanation at this link.

注意,目录必须具有所有的3位集——读、写和执行。好的,R不是绝对必须的,但是w/o你不能列出目录中的条目(所以你必须知道它们的名字)。另一方面执行是绝对需要的- w/o,用户无法读取文件的inode;所以即使有W,没有X文件也不能创建或修改。更详细的解释在此链接。

Finally, the modes are available in the stat module, their descriptions are in inode(7) man.

最后,这些模式在stat模块中是可用的,它们的描述在inode(7)中。

Sample code how to check:

样本代码如何检查:

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