问题:您如何在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类具有内置的chmod和stat方法。
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)