如何在Python中创建临时FIFO(命名管道)?

33 投票
6 回答
63252 浏览
提问于 2025-04-15 14:21

在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(如果他们有合适的权限),那么如果你的程序没有正确处理错误或异常,可能会导致程序崩溃。

撰写回答