如何在python中创建一个具有其他用户可以编写的权限的文件

Ric*_*ard 13 python permissions

我如何在python(3)中创建一个其他用户也可以写的文件.我到目前为止,但它改变了

os.chmod("/home/pi/test/relaxbank1.txt", 777)
with open("/home/pi/test/relaxbank1.txt", "w") as fh:
    fh.write(p1)  
Run Code Online (Sandbox Code Playgroud)

我得到了什么

--- sr-S - t 1 root root 12 Apr 20 13:21 relaxbank1.txt

预期(在命令行中执行$ sudo chmod 777 relaxbank1.txt)

-rwxrwxrwx 1 root root 12 Apr 20 13:21 relaxbank1.txt

AXO*_*AXO 39

如果您不想使用os.chmod并且希望使用适当的权限创建文件,那么您可以使用os.open创建适当的文件描述符,然后创建描述open符:

import os
# The default umask is 0o22 which turns off write permission of group and others
os.umask(0)
with open(os.open('filepath', os.O_CREAT | os.O_WRONLY, 0o777), 'w') as fh:
  fh.write(...)
Run Code Online (Sandbox Code Playgroud)

Python 2注意:

Python 2.x中的内置open()不支持按文件描述符打开.使用os.fdopen代替; 否则你会得到:

TypeError: coercing to Unicode: need string or buffer, int found.
Run Code Online (Sandbox Code Playgroud)

  • 这是比接受的答案更好的方法.当您需要创建具有比默认umask更严格的权限的文件时,在创建文件后更新权限是一个安全漏洞. (13认同)
  • 这种解决方案更加优雅和美观。 (3认同)
  • 此代码示例中还有另一个“陷阱”;人们可能会假设`os.O_CREAT | os.O_WRONLY` 是 `open('filepath', 'w')` 通常设置的标志,但这里缺少一个重要的标志 `O_TRUNC`。如果您使用此代码(有时)写入一个已经存在的文件,并且您正在编写的新内容比原始内容短,那么此代码示例将以我相信的方式在文件末尾留下垃圾对于大多数像我这样的非专家来说会感到惊讶,并且与默认的 python 行为不一致。 (3认同)
  • 这是更好的选择,我将其更改为可接受的答案。感谢您努力与我们分享这一点。 (2认同)

use*_*028 16

问题是您open()重新呼叫的呼叫.您需要chmod()在关闭文件后移动到,或者将文件模式更改为w+.

选项1:

with open("/home/pi/test/relaxbank1.txt", "w+") as fh:
    fh.write(p1)
os.chmod("/home/pi/test/relaxbank1.txt", 0o777)
Run Code Online (Sandbox Code Playgroud)

选项2:

os.chmod("/home/pi/test/relaxbank1.txt", 0o777)
with open("/home/pi/test/relaxbank1.txt", "w+") as fh:
    fh.write(p1)
Run Code Online (Sandbox Code Playgroud)

注释:Option1略胜一筹,因为它处理文件可能尚不存在的情况(在这种情况下os.chmod()会引发异常).

  • 这个答案对于未来的读者来说可能是**危险的**。它之所以安全,是因为 OP 要求将权限更改为**限制较少**。未来的读者请注意,如果您想让权限*更具限制性*,这是不安全的。这是因为创建文件和更改权限之间存在时间间隔。因此,恶意代理可能能够在权限更改之前打开文件并使其保持打开状态。请参阅此处的安全解决方案:/sf/answers/3175768431/ (5认同)
  • “ 0o777”中的“ 0o”有什么作用/意义? (2认同)

Iva*_*ali 13

与 AXO 的想法类似,最好使用正确的权限创建文件,opener的参数open()对于此目的似乎非常方便。

import os

def opener(path, flags):
    return os.open(path, flags, 0o777)

os.umask(0)  # Without this, the created file will have 0o777 - 0o022 (default umask) = 0o755 permissions
with open("myfile.txt", "w", opener=opener) as f:
    f.write("myline")
Run Code Online (Sandbox Code Playgroud)

文档中opener

可以通过传递可调用作为开启器来使用自定义开启器。然后通过使用 (file, flags) 调用 opener 来获取文件对象的底层文件描述符。opener 必须返回一个打开的文件描述符(传递 os.open 作为 opener 会产生类似于传递 None 的功能)。