Python模块os.chmod(file, 664)未将权限更改为rw-rw-r--而是变为-w--wx----

146 投票
7 回答
250332 浏览
提问于 2025-04-17 20:11

最近我在使用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为什么对得到正确的结果这么重要呢?

7 个回答

26

使用权限符号(stat.S_I*)而不是直接的八进制数字

如果你使用更有意义的权限符号,而不是直接的神秘数字,你的问题就可以避免了。例如,对于 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 statman 2 chmod 中找到:

S_IRUSR  (00400)  read by owner
S_IWUSR  (00200)  write by owner
S_IXUSR  (00100)  execute/search by owner
S_IRGRP  (00040)  read by group
S_IWGRP  (00020)  write by group
S_IXGRP  (00010)  execute/search by group
S_IROTH  (00004)  read by others
S_IWOTH  (00002)  write by others
S_IXOTH  (00001)  execute/search by others

另一个好处是更好的可移植性,文档中提到过:

注意:虽然Windows支持 chmod(),但你只能用它设置文件的只读标志(通过 stat.S_IWRITEstat.S_IREAD 常量或相应的整数值)。其他所有位都会被忽略。

chmod +x 的用法可以在这里看到: 如何在Python中简单地执行 "chmod +x"?

在Ubuntu 16.04和Python 3.5.2中测试过。

154

对于那些想要类似于以下内容的人:

$ chmod 755 somefile

可以使用:

$ python -c "import os; os.chmod('somefile', 0o755)"

如果你的Python版本低于2.6:

$ python -c "import os; os.chmod('somefile', 0755)"
176

在一个不同的论坛上发现了这个内容。

如果你在想为什么前面的零很重要,那是因为权限是以八进制整数来设置的,而Python会自动把任何带前导零的整数当作八进制来处理。所以,像这样使用 os.chmod("file", 484)(这是十进制)会得到相同的结果。

你现在传递的是664,在八进制中它是1230

在你的情况下,你需要

os.chmod("/tmp/test_file", 436)

[更新] 注意,对于Python 3,你需要在前面加上0o(零和字母o)。例如,0o666

撰写回答