你如何在python中做一个简单的"chmod + x"?

pri*_*stc 103 python chmod

我想在可执行的python脚本中创建一个文件.

import os
import stat
os.chmod('somefile', stat.S_IEXEC)
Run Code Online (Sandbox Code Playgroud)

它似乎os.chmod没有像unix chmod那样"添加"权限.注释掉最后一行后,该文件具有filemode -rw-r--r--,未注释掉,文件模式为---x------.如何u+x在保持其余模式完整的同时添加标志?

Ign*_*ams 169

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

例:

import os
import stat

st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)
Run Code Online (Sandbox Code Playgroud)

  • 使用以下命令使每个人都可执行... stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH.注意:该值与八进制0111相同,因此您可以执行st.st_mode | 0111 (34认同)
  • 这仅使其可由用户执行.海报询问"chmod + x",这使得它可以全面执行(用户,组,世界) (2认同)
  • [我的答案如下](http://stackoverflow.com/a/30463972/119527) 将 R 位复制到 X,正如人们所期望的那样,编译器。 (2认同)
  • 这是一个非Pythonic的答案,可能更具可读性:`subprocess.check_call(['chmod', '+x', 'somefile'])`,让你更轻松地执行像`a+rx`这样的操作。 (2认同)

Jon*_*art 17

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

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

这使得它(或多或少)尊重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)
Run Code Online (Sandbox Code Playgroud)

  • 在Python 3中改变了八进制文字.而不是`0444`,你使用`0o444`.或者,如果你想支持两者,只需写"292". (2认同)
  • 我不知道Python 3已经删除了传统的八进制文字.非常感谢你的帮忙. (2认同)

Cir*_*四事件 10

尊重umask就像chmod +x

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

chmod +x mypath
Run Code Online (Sandbox Code Playgroud)

thena被使用,但与umask

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

这样做的目的是为了让您不会意外授予太多权限。umask 确定新文件的默认权限,例如 umask 为0077,会为当前用户touch newfile.txt生成权限rw,因为 77 将排除组和其他用户(无论如何,触摸默认情况下不会给出 x)。同样,由于掩码的一部分,chmod +x只会+x为用户添加,忽略组和其他内容:您需要、或来强制设置它们。0011chmod o+xchmod g+xchmod go+xchmod a+x

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

#!/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')
Run Code Online (Sandbox Code Playgroud)

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

在 Ubuntu 16.04、Python 3.5.2 中测试。


cs0*_*s01 9

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

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

from pathlib import Path
import stat


f = Path("/path/to/file.txt")
f.chmod(f.stat().st_mode | stat.S_IEXEC)
Run Code Online (Sandbox Code Playgroud)


zer*_*cog 8

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

Python 2:

os.chmod("/somedir/somefile", 0775)
Run Code Online (Sandbox Code Playgroud)

Python 3:

os.chmod("/somedir/somefile", 0o775)
Run Code Online (Sandbox Code Playgroud)

兼容(八进制转换):

os.chmod("/somedir/somefile", 509)
Run Code Online (Sandbox Code Playgroud)

参考权限示例

  • 这应该是os.chmod(“ / somedir / somefile”,0o775) (4认同)

ncm*_*ist 6

你也可以这样做

>>> import os
>>> st = os.stat("hello.txt")
Run Code Online (Sandbox Code Playgroud)

当前文件列表

$ ls -l hello.txt
-rw-r--r--  1 morrison  staff  17 Jan 13  2014 hello.txt
Run Code Online (Sandbox Code Playgroud)

现在就这样做。

>>> os.chmod("hello.txt", st.st_mode | 0o111)
Run Code Online (Sandbox Code Playgroud)

你会在终端中看到这个。

ls -l hello.txt    
-rwxr-xr-x  1 morrison  staff  17 Jan 13  2014 hello.txt
Run Code Online (Sandbox Code Playgroud)

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