标签归档:permissions

pip安装失败,出现以下错误:OSError:[Errno 13]目录权限被拒绝

问题:pip安装失败,出现以下错误:OSError:[Errno 13]目录权限被拒绝

pip install -r requirements.txt失败,但以下情况除外OSError: [Errno 13] Permission denied: '/usr/local/lib/...。有什么问题,我该如何解决?(我正在尝试设置Django

Installing collected packages: amqp, anyjson, arrow, beautifulsoup4, billiard, boto, braintree, celery, cffi, cryptography, Django, django-bower, django-braces, django-celery, django-crispy-forms, django-debug-toolbar, django-disqus, django-embed-video, django-filter, django-merchant, django-pagination, django-payments, django-storages, django-vote, django-wysiwyg-redactor, easy-thumbnails, enum34, gnureadline, idna, ipaddress, ipython, kombu, mock, names, ndg-httpsclient, Pillow, pyasn1, pycparser, pycrypto, PyJWT, pyOpenSSL, python-dateutil, pytz, requests, six, sqlparse, stripe, suds-jurko
Cleaning up...
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 283, in run
    requirement_set.install(install_options, global_options, root=options.root_path)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1436, in install
    requirement.install(install_options, global_options, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 672, in install
    self.move_wheel_files(self.source_dir, root=root)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 902, in move_wheel_files
    pycompile=self.pycompile,
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 206, in move_wheel_files
    clobber(source, lib_dir, True)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 193, in clobber
    os.makedirs(destsubdir)
  File "/usr/lib/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/amqp-1.4.6.dist-info'

pip install -r requirements.txt fails with the exception below OSError: [Errno 13] Permission denied: '/usr/local/lib/.... What’s wrong and how do I fix this? (I am trying to setup Django)

Installing collected packages: amqp, anyjson, arrow, beautifulsoup4, billiard, boto, braintree, celery, cffi, cryptography, Django, django-bower, django-braces, django-celery, django-crispy-forms, django-debug-toolbar, django-disqus, django-embed-video, django-filter, django-merchant, django-pagination, django-payments, django-storages, django-vote, django-wysiwyg-redactor, easy-thumbnails, enum34, gnureadline, idna, ipaddress, ipython, kombu, mock, names, ndg-httpsclient, Pillow, pyasn1, pycparser, pycrypto, PyJWT, pyOpenSSL, python-dateutil, pytz, requests, six, sqlparse, stripe, suds-jurko
Cleaning up...
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 283, in run
    requirement_set.install(install_options, global_options, root=options.root_path)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1436, in install
    requirement.install(install_options, global_options, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 672, in install
    self.move_wheel_files(self.source_dir, root=root)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 902, in move_wheel_files
    pycompile=self.pycompile,
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 206, in move_wheel_files
    clobber(source, lib_dir, True)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 193, in clobber
    os.makedirs(destsubdir)
  File "/usr/lib/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/amqp-1.4.6.dist-info'

回答 0

选项a)创建一个virtualenv,将其激活并安装:

virtualenv .venv
source .venv/bin/activate
pip install -r requirements.txt

选项b)安装在您的homedir中:

pip install --user -r requirements.txt

我的建议使用安全(a)选项,以便该项目的需求不会干扰其他项目的需求。

Option a) Create a virtualenv, activate it and install:

virtualenv .venv
source .venv/bin/activate
pip install -r requirements.txt

Option b) Install in your homedir:

pip install --user -r requirements.txt

My recommendation use safe (a) option, so that requirements of this project do not interfere with other projects requirements.


回答 1

我们真的应该停止建议sudowith 的使用pip install。最好先尝试一下pip install --user。如果失败了,请查看此处的最高职位。

您不应使用的原因sudo如下:

当您使用进行pip操作时sudo,您将以root用户身份从Internet运行任意Python代码,这会带来很大的安全风险。如果有人在PyPI上放置了一个恶意项目,然后安装了该项目,则可以使攻击者具有对计算机的根访问权限。

We should really stop advising the use of sudo with pip install. It’s better to first try pip install --user. If this fails then take a look at the top post here.

The reason you shouldn’t use sudo is as follows:

When you run pip with sudo, you are running arbitrary Python code from the Internet as a root user, which is quite a big security risk. If someone puts up a malicious project on PyPI and you install it, you give an attacker root access to your machine.


回答 2

您试图在系统范围内的路径上安装软件包,而无须这样做。

  1. 通常,您可以根据自己的职责sudo临时获得超级用户 权限以便在系统范围的路径上安装软件包:

     sudo pip install -r requirements.txt

    sudo 在这里找到更多信息。

    实际上,这不是一个好主意,也没有很好的用例,请参阅@wim的评论。

  2. 如果您不想在系统范围内进行更改,则可以使用该标志将该包安装在每用户路径上--user

    它所需要的只是:

     pip install --user runloop requirements.txt
  3. 最后,对于更细粒度的控制,您还可以使用virtualenv,它可能是开发环境的最佳解决方案,尤其是当您正在处理多个项目并希望跟踪每个人的依赖关系时。

    用以下命令激活您的virtualenv

    $ my-virtualenv/bin/activate

    以下命令会将软件包安装在virtualenv内部(而不是系统范围的路径):

    pip install -r requirements.txt

You are trying to install a package on the system-wide path without having the permission to do so.

  1. In general, you can use sudo to temporarily obtain superuser permissions at your responsibility in order to install the package on the system-wide path:

     sudo pip install -r requirements.txt
    

    Find more about sudo here.

    Actually, this is a bad idea and there’s no good use case for it, see @wim’s comment.

  2. If you don’t want to make system-wide changes, you can install the package on your per-user path using the --user flag.

    All it takes is:

     pip install --user runloop requirements.txt
    
  3. Finally, for even finer grained control, you can also use a virtualenv, which might be the superior solution for a development environment, especially if you are working on multiple projects and want to keep track of each one’s dependencies.

    After activating your virtualenv with

    $ my-virtualenv/bin/activate

    the following command will install the package inside the virtualenv (and not on the system-wide path):

    pip install -r requirements.txt


回答 3

只是澄清在Linux(基于ubuntu)上由于权限被拒绝的错误而遭受了很多痛苦之后,什么对我有用,并利用了上面Bert的回答,我现在使用…

$ pip install --user <package-name>

或者如果在需求文件上运行pip …

$ pip install --user -r requirements.txt

并且这些功能对于每个pip安装(包括创建虚拟环境)都可靠地起作用。

然而,干净的解决方案在我进一步的经验已经安装python-virtualenv,并virtualenvwrappersudo apt-get install在系统级。

然后,在虚拟环境中,使用pip install不带--user标志AND不带sudo。整体上更清洁,更安全,更轻松。

Just clarifying what worked for me after much pain in linux (ubuntu based) on permission denied errors, and leveraging from Bert’s answer above, I now use …

$ pip install --user <package-name>

or if running pip on a requirements file …

$ pip install --user -r requirements.txt

and these work reliably for every pip install including creating virtual environments.

However, the cleanest solution in my further experience has been to install python-virtualenv and virtualenvwrapper with sudo apt-get install at the system level.

Then, inside virtual environments, use pip install without the --user flag AND without sudo. Much cleaner, safer, and easier overall.


回答 4

用户没有某些Python安装路径的写许可权。您可以通过以下方式给予许可:

sudo chown -R $USER /absolute/path/to/directory

因此,您应该授予权限,然后尝试再次安装它,如果您有新路径,还应该授予权限:

sudo chown -R $USER /usr/local/lib/python2.7/

User doesn’t have write permission for some Python installation paths. You can give the permission by:

sudo chown -R $USER /absolute/path/to/directory

So you should give permission, then try to install it again, if you have new paths you should also give permission:

sudo chown -R $USER /usr/local/lib/python2.7/

回答 5

如果需要权限,则不能将’pip’与’sudo’一起使用。您可以做一个技巧,以便可以使用“ sudo”并安装软件包。只需在您的pip命令前面放置“ sudo python -m …”即可。

sudo python -m pip install --user -r package_name

If you need permissions, you cannot use ‘pip’ with ‘sudo’. You can do a trick, so that you can use ‘sudo’ and install package. Just place ‘sudo python -m …’ in front of your pip command.

sudo python -m pip install --user -r package_name

回答 6

因此,由于完全不同的原因,我得到了相同的确切错误。由于完全独立但已知的Homebrew + pip错误,我遵循了Google Cloud帮助文档中列出的此变通办法,您可以在主目录中创建.pydistutils.cfg文件。该文件具有特殊的配置,只应将其用于安装某些库。安装软件包后,我应该已经删除了该disutils.cfg文件,但我忘记这样做了。所以对我来说实际上就是

rm ~/.pydistutils.cfg

然后一切正常。当然,如果确实有原因在该文件中有一些配置,那么您将不希望直接对该文件进行管理。但是,如果其他任何人都做了该解决方法,却忘了删除该文件,这对我来说就成功了!

So, I got this same exact error for a completely different reason. Due to a totally separate, but known Homebrew + pip bug, I had followed this workaround listed on Google Cloud’s help docs, where you create a .pydistutils.cfg file in your home directory. This file has special config that you’re only supposed to use for your install of certain libraries. I should have removed that disutils.cfg file after installing the packages, but I forgot to do so. So the fix for me was actually just…

rm ~/.pydistutils.cfg.

And then everything worked as normal. Of course, if you have some config in that file for a real reason, then you won’t want to just straight rm that file. But in case anyone else did that workaround, and forgot to remove that file, this did the trick for me!


回答 7

是适当的许可问题,

sudo chown -R $USER /path to your python installed directory

默认是 /usr/local/lib/python2.7/

或尝试

pip install --user -r package_name

然后说,pip install -r requirements.txt这将安装在您的环境中

不要说,sudo pip install -r requirements.txt这将安装到任意python路径中。

It is due permission problem,

sudo chown -R $USER /path to your python installed directory

default it would be /usr/local/lib/python2.7/

or try,

pip install --user -r package_name

and then say, pip install -r requirements.txt this will install inside your env

dont say, sudo pip install -r requirements.txt this is will install into arbitrary python path.


Python模块os.chmod(file,664)不会将权限更改为rw-rw-r,而是-w–wx —-

问题:Python模块os.chmod(file,664)不会将权限更改为rw-rw-r,而是-w–wx —-

最近,我正在使用Python模块os,当我尝试更改文件的权限时,没有得到预期的结果。例如,我打算将权限更改为rw-rw-r–,

os.chmod("/tmp/test_file", 664)

所有权许可实际上是-w–wx —(230)

--w--wx--- 1 ag ag 0 Mar 25 05:45 test_file

但是,如果我在代码中将664更改为0664,则结果正是我所需要的,例如

os.chmod("/tmp/test_file", 0664)

结果是:

-rw-rw-r-- 1 ag ag 0 Mar 25 05:55 test_file

任何人都可以帮助解释为什么前导0对于获得正确结果如此重要吗?

Recently I am using Python module os, when I tried to change the permission of a file, I did not get the expected result. For example, I intended to change the permission to rw-rw-r–,

os.chmod("/tmp/test_file", 664)

The ownership permission is actually -w–wx— (230)

--w--wx--- 1 ag ag 0 Mar 25 05:45 test_file

However, if I change 664 to 0664 in the code, the result is just what I need, e.g.

os.chmod("/tmp/test_file", 0664)

The result is:

-rw-rw-r-- 1 ag ag 0 Mar 25 05:55 test_file

Could anybody help explaining why does that leading 0 is so important to get the correct result?


回答 0

其他论坛上找到了这个

如果您想知道为什么前导零很重要,那是因为将权限设置为八进制整数,Python自动将任何带有前导零的整数视为八进制。因此os.chmod(“ file”,484)(十进制)将给出相同的结果。

您正在做的是通过664八进制的1230

在您的情况下,您将需要

os.chmod("/tmp/test_file", 436)

[更新]请注意,对于Python 3,您的前缀为0o(零哦)。例如,0o666

Found this on a different forum

If you’re wondering why that leading zero is important, it’s because permissions are set as an octal integer, and Python automagically treats any integer with a leading zero as octal. So os.chmod(“file”, 484) (in decimal) would give the same result.

What you are doing is passing 664 which in octal is 1230

In your case you would need

os.chmod("/tmp/test_file", 436)

[Update] Note, for Python 3 you have prefix with 0o (zero oh). E.G, 0o666


回答 1

因此,对于那些想要类似语义的人:

$ chmod 755 somefile

用:

$ python -c "import os; os.chmod('somefile', 0o755)"

如果您的Python早于2.6:

$ python -c "import os; os.chmod('somefile', 0755)"

So for people who want semantics similar to:

$ chmod 755 somefile

Use:

$ python -c "import os; os.chmod('somefile', 0o755)"

If your Python is older than 2.6:

$ python -c "import os; os.chmod('somefile', 0755)"

回答 2

前导0意味着这是八进制常数,而不是十进制数。并且您需要八进制更改文件模式。

权限是一个位掩码,例如,rwxrwx---111111000二进制的,并且将位除以3来转换为八进制,这比计算十进制表示形式要容易得多。

0644(八进制)为0.110.100.100二进制(为了可读性,添加了点),或者,如您所计算的,420十进制。

leading 0 means this is octal constant, not the decimal one. and you need an octal to change file mode.

permissions are a bit mask, for example, rwxrwx--- is 111111000 in binary, and it’s very easy to group bits by 3 to convert to the octal, than calculate the decimal representation.

0644 (octal) is 0.110.100.100 in binary (i’ve added dots for readability), or, as you may calculate, 420 in decimal.


回答 3

使用权限符号代替数字

如果您使用了语义上更命名的权限符号而不是原始的魔术数字,则可以避免您的问题,例如664

#!/usr/bin/env python3

import os
import stat

os.chmod(
    'myfile',
    stat.S_IRUSR |
    stat.S_IWUSR |
    stat.S_IRGRP |
    stat.S_IWGRP |
    stat.S_IROTH
)

https://docs.python.org/3/library/os.html#os.chmod中对此进行了记录,其名称与在处记录的POSIX C API值相同man 2 stat

另一个优点是文档中提到的更大的可移植性:

注意:尽管Windows支持chmod(),但您只能使用它设置文件的只读标志(通过stat.S_IWRITEstat.S_IREAD常数或相应的整数值)。所有其他位均被忽略。

chmod +x演示于:如何在python中执行简单的“ chmod + x”?

已在Ubuntu 16.04,Python 3.5.2中进行了测试。

Use permission symbols instead of numbers

Your problem would have been avoided if you had used the more semantically named permission symbols rather than raw magic numbers, e.g. for 664:

#!/usr/bin/env python3

import os
import stat

os.chmod(
    'myfile',
    stat.S_IRUSR |
    stat.S_IWUSR |
    stat.S_IRGRP |
    stat.S_IWGRP |
    stat.S_IROTH
)

This is documented at https://docs.python.org/3/library/os.html#os.chmod and the names are the same as the POSIX C API values documented at man 2 stat.

Another advantage is the greater portability as mentioned in the docs:

Note: Although Windows supports chmod(), you can only set the file’s read-only flag with it (via the stat.S_IWRITE and stat.S_IREAD constants or a corresponding integer value). All other bits are ignored.

chmod +x is demonstrated at: How do you do a simple “chmod +x” from within python?

Tested in Ubuntu 16.04, Python 3.5.2.


回答 4

如果您已将所需的权限保存到字符串,请执行

s = '660'
os.chmod(file_path, int(s, base=8))

If you have desired permissions saved to string then do

s = '660'
os.chmod(file_path, int(s, base=8))

回答 5

在我看来,使用stat。*位掩码似乎是最方便,最明确的方式。但另一方面,我经常忘记如何最好地处理该问题。因此,这是一个掩盖“组”和“其他”权限并保持“所有者”权限不变的示例。使用位掩码和减法是一种有用的模式。

import os
import stat
def chmodme(pn):
    """Removes 'group' and 'other' perms. Doesn't touch 'owner' perms."""
    mode = os.stat(pn).st_mode
    mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
    os.chmod(pn, mode)

Using the stat.* bit masks does seem to me the most portable and explicit way of doing this. But on the other hand, I often forget how best to handle that. So, here’s an example of masking out the ‘group’ and ‘other’ permissions and leaving ‘owner’ permissions untouched. Using bitmasks and subtraction is a useful pattern.

import os
import stat
def chmodme(pn):
    """Removes 'group' and 'other' perms. Doesn't touch 'owner' perms."""
    mode = os.stat(pn).st_mode
    mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
    os.chmod(pn, mode)

确定目录是否可写

问题:确定目录是否可写

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

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.


回答 0

尽管Christophe建议的是更Python化的解决方案,但os模块确实具有os.access函数来检查访问:

os.access('/path/to/folder', os.W_OK) #W_OK用于写入,R_OK用于读取,等等。

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

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


回答 1

提出这个建议似乎很奇怪,但是一个常见的Python习惯用法是

寻求宽恕比获得许可要容易

遵循这一习语,人们可能会说:

尝试写入有问题的目录,如果没有权限,则捕获错误。

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

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.


回答 2

我使用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

那时在这些情况下当然仍然存在延迟。

My solution using the tempfile module:

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

Update: After testing the code again on Windows I see that there is indeed an issue when using tempfile there, see issue22107: tempfile module misinterprets access denied error on Windows. In the case of a non-writable directory, the code hangs for several seconds and finally throws an IOError: [Errno 17] No usable temporary file name found. Maybe this is what user2171842 was observing? Unfortunately the issue is not resolved for now so to handle this, the error needs to be catched as well:

    except (OSError, IOError) as e:
        if e.errno == errno.EACCES or e.errno == errno.EEXIST:  # 13, 17

The delay is of course still present in these cases then.


回答 3

偶然发现该线程在寻找某人的示例。恭喜,您在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")

这会尝试打开文件句柄进行写入,如果指定的文件无法写入,则会退出并返回错误:这更容易阅读,并且比对文件路径或目录进行预检查要好得多,因为它避免了比赛条件;在运行预检查的时间到实际尝试写入文件之间文件不可写的情况。

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:

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.


回答 4

如果您只关心文件烫发,os.access(path, os.W_OK)应按要求进行操作。相反,如果您想知道是否可以写入该目录,则可以编写open()一个用于写入的测试文件(该文件不应事先存在),捕获并检查其中的任何IOError文件,然后清理该测试文件。

更一般而言,为避免TOCTOU攻击(仅当脚本以提升的特权-suid或cgi或更高的特权运行时才出现问题),您不应该真正信任这些提前测试,而应该放弃privs,执行open()并期望的IOError

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.

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.


回答 5

检查模式位:

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

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

回答 6

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

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

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

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

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

 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


回答 8

通过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,一切似乎都可以正常运行了。

I ran into this same need while adding an argument via argparse. The built in type=FileType('w') wouldn’t work for me as I was looking for a directory. I ended up writing my own method to solve my problem. Here is the result with argparse snippet.

#! /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()

That results in the following:

$ 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 ~

I went back and added print opts.dir to the end, and everything appears to be functioning as desired.


回答 9

如果您需要检查其他用户的权限(是的,我知道这与问题相矛盾,但可能对某人有用),则可以通过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

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.

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.

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.

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

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