我想从Python脚本中创建一个可执行的文件。
import os
import stat
os.chmod('somefile', stat.S_IEXEC)
看起来os.chmod
无法像unix中的chmod
那样“添加”权限。如果将最后一行注释掉,文件的文件模式为-rw-r--r--
,如果不注释,则文件模式为---x------
。如何在保持其余模式不变的情况下仅添加u+x
标志?
使用 os.stat()
获取当前权限,使用 |
来对位进行 OR 操作,然后使用 os.chmod()
来设置更新后的权限。
示例:
import os
import stat
st = os.stat('somefile')
os.chmod('somefile', st.st_mode | stat.S_IEXEC)
对于生成可执行文件(例如脚本)的工具,下面的代码可能会有所帮助:
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)
0o444
代替 0444
。或者,如果你想要同时支持两种写法,可以直接写 292
。 - Kevinos.chmod("path", os.stat("path").st_mode | 0o111)
这行代码与下面的代码有相同的效果,但是它只有一行。 - Aarav Prasad如果您知道所需的权限,则以下示例可能是保持简单的方法。
Python 2:
os.chmod("/somedir/somefile", 0775)
Python 3:
os.chmod("/somedir/somefile", 0o775)
兼容以下两种格式(八进制转换):
os.chmod("/somedir/somefile", 509)
参考 权限示例
像使用 chmod +x
一样尊重 umask
man chmod
命令中提到,如果未指定 augo
参数:
chmod +x mypath
接下来使用a
,但同时使用umask
:
字母组合(u)ser、(g)roup、(o)ther和(a)ll控制着将更改哪些用户对文件的访问权限:拥有文件的用户(u)、文件所属组中的其他用户(g)、未在文件所属组中的其他用户(o)或所有用户(a)。如果没有指定上述任何选项,则效果好像指定了(a),但是受到umask设置的位不会受到影响。
这样做的目的是为了避免意外赋予过多权限。umask决定了新文件的默认权限,例如umask为0077
,则touch newfile.txt
产生的权限为当前用户的rw
,因为77会排除组和其他权限(touch默认情况下也不会提供x权限)。同样地,由于掩码的0011
部分,chmod +x
只会增加用户的+x
权限,忽略组和其他权限,您需要使用chmod o+x
、chmod g+x
、chmod go+x
或chmod 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')
在Ubuntu 16.04,Python 3.5.2中测试通过。
>>> 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使所有文件可读取。
os.chmod("path", os.stat("path").st_mode | 0o111)
在Python3中:
import os
os.chmod("somefile", 0o664)
记得添加0o
前缀,因为权限设置是八进制整数,而Python自动将任何具有前导零的整数视为八进制。否则,您实际上正在传递os.chmod(“somefile”,1230)
,这是664
的八进制。
chmod +
那样添加新权限到现有权限上。 - Ciro Santilli OurBigBook.com我们可以使用os.system()
在Python中直接调用chmod +x
命令。
import os
os.system("chmod +x somefile")
STAT_OWNER_EXECUTABLE = stat.S_IEXEC
,并使用可读性更好的本地常量,而不是无意义的常量。 - ThorSummonersubprocess.check_call(['chmod', '+x', 'somefile'])
,并且可以更轻松地执行像a+rx
这样的操作。 - Trevor Boyd Smith