如何在Python中创建临时FIFO(命名管道)?
在Python中,如何创建一个临时的FIFO(命名管道)呢?这个方法应该可以用:
import tempfile
temp_file_name = mktemp()
os.mkfifo(temp_file_name)
open(temp_file_name, os.O_WRONLY)
# ... some process, somewhere, will read it ...
不过,我有点犹豫,因为在Python文档11.6中有个大警告,而且这个功能可能会被移除,因为它已经不再推荐使用了。
补充说明:值得一提的是,我试过使用tempfile.NamedTemporaryFile
(以及tempfile.mkstemp
),但是os.mkfifo
会报错:
OSError -17: 文件已经存在
当你在mkstemp/NamedTemporaryFile创建的文件上运行它时,会出现这个错误。
6 个回答
5
那用这个怎么样呢
d = mkdtemp()
t = os.path.join(d, 'fifo')
10
你可能会觉得使用下面这个上下文管理器很方便,它可以帮你创建和删除临时文件:
import os
import tempfile
from contextlib import contextmanager
@contextmanager
def temp_fifo():
"""Context Manager for creating named pipes with temporary names."""
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'fifo') # Temporary filename
os.mkfifo(filename) # Create FIFO
try:
yield filename
finally:
os.unlink(filename) # Remove file
os.rmdir(tmpdir) # Remove directory
你可以像这样使用它:
with temp_fifo() as fifo_file:
# Pass the fifo_file filename e.g. to some other process to read from.
# Write something to the pipe
with open(fifo_file, 'w') as f:
f.write("Hello\n")
32
os.mkfifo()
这个函数如果你试图创建一个已经存在的文件,就会报错 OSError: [Errno 17] File exists
,所以这里没有安全隐患。使用 tempfile.mktemp()
的安全问题在于“竞争条件”,也就是说攻击者可以在你打开文件之前,先创建一个同名的文件,但因为 os.mkfifo()
如果文件已经存在就会失败,所以这个问题在这里不存在。
不过,由于 mktemp()
已经不推荐使用了,所以你应该用 tempfile.mkdtemp()
来代替:
import os, tempfile
tmpdir = tempfile.mkdtemp()
filename = os.path.join(tmpdir, 'myfifo')
print filename
try:
os.mkfifo(filename)
except OSError, e:
print "Failed to create FIFO: %s" % e
else:
fifo = open(filename, 'w')
# write stuff to fifo
print >> fifo, "hello"
fifo.close()
os.remove(filename)
os.rmdir(tmpdir)
补充说明:我需要强调的是,虽然 mktemp()
的漏洞被避免了,但还有其他常见的安全问题需要考虑;比如,如果攻击者在你的程序之前创建了 fifo(如果他们有合适的权限),那么如果你的程序没有正确处理错误或异常,可能会导致程序崩溃。