标签归档:chmod

您如何在python中执行简单的“ chmod + x”操作?

问题:您如何在python中执行简单的“ chmod + x”操作?

我想从可执行的python脚本中创建文件。

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

它似乎os.chmod没有像unix chmod那样“添加”权限。在最后一行注释掉的情况下,文件具有filemode -rw-r--r--,而在未注释掉的情况下,文件模式为---x------。如何u+x在保持其余模式不变的同时添加标志?

I want to create a file from within a python script that is executable.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)

it appears os.chmod doesn’t ‘add’ permissions the way unix chmod does. With the last line commented out, the file has the filemode -rw-r--r--, with it not commented out, the file mode is ---x------. How can I just add the u+x flag while keeping the rest of the modes intact?


回答 0

使用os.stat()得到当前的权限,使用|或位在一起,并使用os.chmod()设置更新的权限。

例:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)

Use os.stat() to get the current permissions, use | to or the bits together, and use os.chmod() to set the updated permissions.

Example:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)

回答 1

对于生成可执行文件的工具(例如脚本),以下代码可能会有所帮助:

def make_executable(path):
    mode = os.stat(path).st_mode
    mode |= (mode & 0o444) >> 2    # copy R bits to X
    os.chmod(path, mode)

这使它(或多或少)尊重umask创建文件时的效果:仅为可读取的文件设置可执行文件。

用法:

path = 'foo.sh'
with open(path, 'w') as f:           # umask in effect when file is created
    f.write('#!/bin/sh\n')
    f.write('echo "hello world"\n')

make_executable(path)

For tools that generate executable files (e.g. scripts), the following code might be helpful:

def make_executable(path):
    mode = os.stat(path).st_mode
    mode |= (mode & 0o444) >> 2    # copy R bits to X
    os.chmod(path, mode)

This makes it (more or less) respect the umask that was in effect when the file was created: Executable is only set for those that can read.

Usage:

path = 'foo.sh'
with open(path, 'w') as f:           # umask in effect when file is created
    f.write('#!/bin/sh\n')
    f.write('echo "hello world"\n')

make_executable(path)

回答 2

如果知道所需的权限,则可以使用以下示例来简化操作。

Python 2:

os.chmod("/somedir/somefile", 0775)

Python 3:

os.chmod("/somedir/somefile", 0o775)

兼容(八进制转换):

os.chmod("/somedir/somefile", 509)

参考权限示例

If you know the permissions you want then the following example may be the way to keep it simple.

Python 2:

os.chmod("/somedir/somefile", 0775)

Python 3:

os.chmod("/somedir/somefile", 0o775)

Compatible with either (octal conversion):

os.chmod("/somedir/somefile", 509)

reference permissions examples


回答 3

您也可以这样做

>>> import os
>>> st = os.stat("hello.txt")

当前文件清单

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt

现在做。

>>> os.chmod("hello.txt", st.st_mode | 0o111)

然后您将在终端中看到此内容。

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt

您可以按位或0o111使所有可执行文件,0o222使所有可写,和0o444使所有可读。

You can also do this

>>> import os
>>> st = os.stat("hello.txt")

Current listing of file

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt

Now do this.

>>> os.chmod("hello.txt", st.st_mode | 0o111)

and you will see this in the terminal.

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt

You can bitwise or with 0o111 to make all executable, 0o222 to make all writable, and 0o444 to make all readable.


回答 4

尊重umask喜欢chmod +x

man chmod说如果augo没有给出,如:

chmod +x mypath

然后a使用,但与umask

字母ugoa的组合控制将更改哪些用户对该文件的访问权限:拥有该文件的用户(u),该文件组中的其他用户(g),不在该文件组中的其他用户(o)或全部用户(a)。如果没有给出这些,则效果就好像给出了(a)一样,但是不影响umask中设置的位。

这是一个完全模拟该行为的版本:

#!/usr/bin/env python3

import os
import stat

def get_umask():
    umask = os.umask(0)
    os.umask(umask)
    return umask

def chmod_plus_x(path):
    os.chmod(
        path,
        os.stat(path).st_mode |
        (
            (
                stat.S_IXUSR |
                stat.S_IXGRP |
                stat.S_IXOTH
            )
            & ~get_umask()
        )
    )

chmod_plus_x('.gitignore')

另请参阅:如何获取Python中的默认文件权限?

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

Respect umask like chmod +x

man chmod says that if augo is not given as in:

chmod +x mypath

then a is used but with umask:

A combination of the letters ugoa controls which users’ access to the file will be changed: the user who owns it (u), other users in the file’s group (g), other users not in the file’s group (o), or all users (a). If none of these are given, the effect is as if (a) were given, but bits that are set in the umask are not affected.

Here is a version that simulates that behavior exactly:

#!/usr/bin/env python3

import os
import stat

def get_umask():
    umask = os.umask(0)
    os.umask(umask)
    return umask

def chmod_plus_x(path):
    os.chmod(
        path,
        os.stat(path).st_mode |
        (
            (
                stat.S_IXUSR |
                stat.S_IXGRP |
                stat.S_IXOTH
            )
            & ~get_umask()
        )
    )

chmod_plus_x('.gitignore')

See also: How can I get the default file permissions in Python?

Tested in Ubuntu 16.04, Python 3.5.2.


回答 5

在python3中:

import os
os.chmod("somefile", 0o664)

请记住要添加0o前缀,因为权限设置为八进制整数,Python会自动将前导零的任何整数视为八进制。否则,您os.chmod("somefile", 1230)的确通过了,这是的八进制664

In python3:

import os
os.chmod("somefile", 0o664)

Remember to add the 0o prefix since permissions are set as an octal integer, and Python automatically treats any integer with a leading zero as octal. Otherwise, you are passing os.chmod("somefile", 1230) indeed, which is octal of 664.


回答 6

如果您使用的是Python 3.4+,则可以使用标准库的便捷pathlib

它的Path类具有内置的chmodstat方法。

from pathlib import Path


f = Path("/path/to/file.txt")
f.chmod(f.stat().st_mode | stat.S_IEXEC)

If you’re using Python 3.4+, you can use the standard library’s convenient pathlib.

Its Path class has built-in chmod and stat methods.

from pathlib import Path
import stat


f = Path("/path/to/file.txt")
f.chmod(f.stat().st_mode | stat.S_IEXEC)

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)