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


119

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

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

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

Answers:


197

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

例:

import os
import stat

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

2
这仅使其可由用户执行。张贴者询问“ chmod + x”问题,使其可以全面执行(用户,组,世界)
eric.frederich 2013年

35
使用以下命令使每个人都可以执行... stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH。注意:该值与八进制0111相同,因此您可以执行st.st_mode | 0111
eric.frederich

1
我在下面的回答将R位复制到X,就像一个编译器所期望的那样。
乔纳森·莱因哈特

我会这样做STAT_OWNER_EXECUTABLE = stat.S_IEXEC,并使用人类可读的局部常量代替乱码。
ThorSummoner

这是一个非Python的答案,可能会更具可读性:subprocess.check_call(['chmod', '+x', 'somefile'])并且让您更轻松地执行a+rx
Trevor Boyd Smith

20

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

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)

2
在Python 3中更改了八进制文字。0444您可以使用代替0o444。或者,如果您想同时支持两者,则只需编写292
凯文

1
@Kevin 看起来 Python 2.6已支持新语法,因此使用它似乎是合理的。(有关兼容性的参考点,CentOS 6随附了Python 2.6)。
Jonathon Reinhart

2
我没有意识到Python 3已经删除了传统的八进制文字。非常感谢你的帮忙。
乔纳森·莱因哈特

12

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

Python 2:

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

Python 3:

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

兼容(八进制转换):

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

参考权限示例


4
这应该是os.chmod(“ / somedir / somefile”,0o775)
ang mo

4

您也可以这样做

>>> 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使所有可读。


2

尊重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中进行了测试。


1

在python3中:

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

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


1
这确实将权限设置为绝对值,而不是chmod +OP要求的操作,OP应该向现有的权限添加新的权限。
西罗Santilli郝海东冠状病六四事件法轮功

0

如果您使用的是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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.