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


110

最近,我正在使用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对于获得正确结果如此重要吗?


33
八进制。八进制。八进制。
科尔·约翰逊

6
我在bugs.python.org/issue25377中打开了python文档的问题,因为从文档中应该可以清楚地看出这一点。
2015年

Answers:


130

其他论坛上找到了这个

如果您想知道为什么前导零很重要,那是因为将权限设置为八进制整数,Python自动将任何带有前导零的整数视为八进制。因此os.chmod(“ file”,484)(十进制)将给出相同的结果。

您正在做的是通过664八进制的1230

在您的情况下,您将需要

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

[更新]请注意,对于Python 3,您的前缀为0o(零哦)。例如,0o666


1
谢谢,但我仍然感到困惑,十进制数484表示八进制数744,这在您在论坛中提到的线程中是有意义的。但是,如果我用十进制表示644,则以八进制表示为1204。1204与八进制的230有什么关系?
AplusG

2
@AplusG:该1不会放弃!那是粘滞/ setuid / setgid位,1表示sticky。使用ls -l您可能会注意到权限现在T最终包括了...
MestreLion 2014年

2
更容易添加0并使其八进制:)
radtek

10
请注意,对于Python 3,您的前缀为0o(零哦)。
Mawg说恢复Monica 2015年

1
我在python 2.7.10使用0°
Wyrmwood

124

因此,对于那些想要类似语义的人:

$ chmod 755 somefile

用:

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

如果您的Python早于2.6:

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

12
python3格式也适用于python 2.7.9。我尚未检查早期版本。
Fred Mitchell

3
Python 3语法可回溯至Python 2.6docs.python.org/3/whatsnew/…–
Pete,

为我工作!
LandiLeite

应该是00755,只是为了弄清楚suid / sgid / sticky位在哪里,以防万一后来的一些开发人员想使用这个旧脚本,例如,使用sgid 2755但又不知道为什么烫发完全搞砸了。;)
dannysauer

10

前导0意味着这是八进制常数,而不是十进制数。并且您需要八进制更改文件模式。

权限是一个位掩码,例如,rwxrwx---111111000二进制的,并且将位除以3来转换为八进制,这比计算十进制表示形式要容易得多。

0644(八进制)为0.110.100.100二进制(为了可读性,添加了点),或者,如您所计算的,420十进制。


5

使用权限符号代替数字

如果您使用了语义上更命名的权限符号而不是原始的魔术数字,则可以避免您的问题,例如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 stat

另一个优点是文档中提到的更大的可移植性:

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

chmod +x演示于:如何在python中执行简单的“ chmod + x”?

已在Ubuntu 16.04,Python 3.5.2中进行了测试。


1
这是处理问题的正确方法。
卡瑟斯

我知道这是python方式,但很难做到:)
Tomasz Swider

2

如果您已将所需的权限保存到字符串,请执行

s = '660'
os.chmod(file_path, int(s, base=8))

0

在我看来,使用stat。*位掩码似乎是最方便,最明确的方式。但另一方面,我经常忘记如何最好地处理该问题。因此,这是一个掩盖“组”和“其他”权限并保持“所有者”权限不变的示例。使用位掩码和减法是一种有用的模式。

import os
import stat
def chmodme(pn):
    """Removes 'group' and 'other' perms. Doesn't touch 'owner' perms."""
    mode = os.stat(pn).st_mode
    mode -= (mode & (stat.S_IRWXG | stat.S_IRWXO))
    os.chmod(pn, mode)
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.