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

Bri*_*unt 27 python security file fifo mkfifo

如何在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 ...
Run Code Online (Sandbox Code Playgroud)

但是,由于Python Docs 11.6中的重大警告以及潜在的删除,我犹豫不决,因为它已被弃用.

编辑:值得注意的是,我已尝试tempfile.NamedTemporaryFile(并通过扩展tempfile.mkstemp),但os.mkfifo抛出:

OSError -17:文件已存在

当您在mkstemp/NamedTemporaryFile创建的文件上运行它时.

mha*_*wke 26

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)
Run Code Online (Sandbox Code Playgroud)

编辑:我应该明确指出,仅仅因为mktemp()避免了漏洞,还有其他常见的安全问题需要考虑; 例如,攻击者可以在程序执行之前创建fifo(如果他们有合适的权限),如果没有正确处理错误/异常,可能会导致程序崩溃.

  • `os.rmdir(tmpdir)`不应该在try-else块之外吗? (6认同)
  • 您的意思是“ OSError除外为e”。 (2认同)

bre*_*dan 5

怎么样使用

d = mkdtemp()
t = os.path.join(d, 'fifo')
Run Code Online (Sandbox Code Playgroud)


nir*_*msu 5

您可能会发现使用以下上下文管理器很方便,该上下文管理器会为您创建和删除临时文件:

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
    yield filename
    os.unlink(filename)  # Remove file
    os.rmdir(tmpdir)  # Remove directory
Run Code Online (Sandbox Code Playgroud)

您可以使用它,例如,像这样:

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")
Run Code Online (Sandbox Code Playgroud)