Python模块os.chmod(file,664)不会改变对rw-rw-r--的权限,但是-w - wx ----

Apl*_*usG 99 python permissions file chmod

最近我使用的是Python模块os,当我试图更改文件的权限时,我没有得到预期的结果.例如,我打算将权限更改为rw-rw-r--,

os.chmod("/tmp/test_file", 664)
Run Code Online (Sandbox Code Playgroud)

所有权许可实际上是-w - wx ---(230)

--w--wx--- 1 ag ag 0 Mar 25 05:45 test_file
Run Code Online (Sandbox Code Playgroud)

但是,如果我在代码中将664更改为0664,结果就是我需要的,例如

os.chmod("/tmp/test_file", 0664)
Run Code Online (Sandbox Code Playgroud)

结果是:

-rw-rw-r-- 1 ag ag 0 Mar 25 05:55 test_file
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助解释为什么领先的0对于获得正确的结果如此重要?

Dim*_*ima 118

对于那些想要语义相似的人:

$ chmod 755 somefile
Run Code Online (Sandbox Code Playgroud)

在python 2中:

$ python -c "import os; os.chmod('somefile', 0o755)"
Run Code Online (Sandbox Code Playgroud)

在python 3中:

$ python -c "import os; os.chmod('somefile', 0755)"
Run Code Online (Sandbox Code Playgroud)

  • python3格式也适用于python 2.7.9.我没有检查过早期版本. (11认同)
  • Python 3语法可回溯至Python 2.6 https://docs.python.org/3/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax (2认同)

Red*_*ron 115

另一个论坛上找到了这个

如果你想知道为什么前导零是重要的,那是因为权限被设置为八进制整数,并且Python自动将任何具有前导零的整数视为八进制.所以os.chmod("file",484)(十进制)会给出相同的结果.

你正在做的是传递664八进制的1230

在你的情况下,你需要

os.chmod("/tmp/test_file", 436)
Run Code Online (Sandbox Code Playgroud)

[更新]注意,对于Python 3,你的前缀是0o(零哦).例如,0o666

  • 请注意,对于Python 3,您的前缀为0o(零哦). (9认同)
  • 我在 python 2.7.10 中使用 0o (3认同)
  • @AplusG:`1`被***丢弃了!这是sticky/setuid/setgid位,1表示"粘性".使用`ls -l`你可能会注意到权限现在包括一个`T` ... (2认同)
  • 更容易添加0并使其成为八进制:) (2认同)

Cir*_*四事件 11

使用权限符号 ( 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
)
Run Code Online (Sandbox Code Playgroud)

这记录在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
Run Code Online (Sandbox Code Playgroud)

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

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

chmod +x演示在:How do you do a simple "chmod +x" from within python?

在 Ubuntu 16.04、Python 3.5.2 中测试。

  • 我知道这是 python 的方式,但它几乎不可能更丑了:) (6认同)
  • 这才是处理问题的正确方法。 (2认同)

len*_*nik 9

前导"0"表示这是八进制常量,而不是十进制常量.你需要一个八进制来改变文件模式.

权限是一个位掩码,例如,rwxrwx ---是二进制的111111000,并且很容易将位分组3转换为八进制,而不是计算十进制表示.

0644(八进制)是二进制的0.110.100.100(为了便于阅读,我添加了点),或者,如您所计算,小数为420.


mc.*_*dev 6

如果你有想要的权限保存到字符串然后做

s = '660'
os.chmod(file_path, int(s, base=8))
Run Code Online (Sandbox Code Playgroud)


Mik*_*e R 5

@mc.dev 的答案是最好的答案,我最终利用它来制作下面的函数包装器以供重用。感谢您的分享。

def chmod_digit(file_path, perms):
    """
    Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself.
    Credits: /sf/answers/4203699321/
    """
    os.chmod(file_path, int(str(perms), base=8))
Run Code Online (Sandbox Code Playgroud)