lfa*_*one 51 python permissions file-io
我正在尝试创建一个只有用户可读和可写(0600)的文件.
这是通过以下方式使用的唯一方法os.open()吗?
import os
fd = os.open('/path/to/file', os.O_WRONLY, 0o600)
myFileObject = os.fdopen(fd)
myFileObject.write(...)
myFileObject.close()
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够使用with关键字,以便我可以自动关闭对象.有没有更好的方法来做我上面做的事情?
var*_*tec 36
有什么问题?file.close()将关闭该文件,即使它已打开os.open().
with os.fdopen(os.open('/path/to/file', os.O_WRONLY | os.O_CREAT, 0o600), 'w') as handle:
handle.write(...)
Run Code Online (Sandbox Code Playgroud)
Acu*_*nus 28
这个答案解决了vartec对答案的多重顾虑,尤其是umask关注点.
import os
import stat
# Define file params
fname = '/tmp/myfile'
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL # Refer to "man 2 open".
mode = stat.S_IRUSR | stat.S_IWUSR # This is 0o600.
umask = 0o777 ^ mode # Prevents always downgrading umask to 0.
# For security, remove file with potentially elevated mode
try:
os.remove(fname)
except OSError:
pass
# Open file descriptor
umask_original = os.umask(umask)
try:
fdesc = os.open(fname, flags, mode)
finally:
os.umask(umask_original)
# Open file handle and write to file
with os.fdopen(fdesc, 'w') as fout:
fout.write('something\n')
Run Code Online (Sandbox Code Playgroud)
如果是所需模式0600,则可以更明确地将其指定为八进制数0o600.更好的是,只需使用该stat模块.
即使首先删除旧文件,仍然可以进行竞争条件.包括os.O_EXCL与os.O_CREAT如果存在因竞争条件的标志将防止创建的文件.这是一种必要的辅助安全措施,可防止打开可能已存在且可能已升高的文件mode.在Python 3中,FileExistsError如果文件存在,则引发[Errno 17].
未能首先设置umaskto 0或to 0o777 ^ mode可能导致设置不正确mode(权限)os.open.这是因为默认umask值通常不是0,它将应用于指定的mode.例如,如果我原来umask是2即0o002和我指定的模式是0o222,如果我不先设置umask,生成的文件可以改为具有mode的0o220,这不是我想要的东西.Per man 2 open,创建文件的模式是mode & ~umask.
该umask是尽快恢复到原来的值.此获取和设置不是线程安全的,并且threading.Lock必须在多线程应用程序中使用.
有关umask的更多信息,请参阅此主题.
jsb*_*eno 12
更新
人们,虽然我感谢你们在这里的赞成,我自己不得不反对我最初提出的解决方案.原因在于以这种方式做事,文件确实存在时会有一段时间,无论多么小,并且没有适当的权限 - 这会留下广泛的攻击方式,甚至是错误的行为.
当然,首先使用正确的权限创建文件是要走的路 - 正确性,使用Python with只是一些糖果.
所以,请把这个答案作为"什么不该做"的例子;
原帖
你可以os.chmod改用:
>>> import os
>>> name = "eek.txt"
>>> with open(name, "wt") as myfile:
... os.chmod(name, 0o600)
... myfile.write("eeek")
...
>>> os.system("ls -lh " + name)
-rw------- 1 gwidion gwidion 4 2011-04-11 13:47 eek.txt
0
>>>
Run Code Online (Sandbox Code Playgroud)
(请注意,在Python中使用octals的方法是明确的 - 通过在"\n"中添加前缀0o" 0o600".在Python 2.x中它只能编写0600- 但这既误导又弃用.)
但是,如果您的安全性很关键,那么您可能应该os.open像使用它一样创建它并使用os.fdopen从返回的文件描述符中检索Python File对象os.open.
| 归档时间: |
|
| 查看次数: |
59206 次 |
| 最近记录: |