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

发布于 2024-08-05 01:29:38 字数 628 浏览 10 评论 0原文

如何在 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 Docs 11.6 中的大警告,我很犹豫以及可能被删除,因为它已被弃用。

编辑:值得注意的是,我尝试过tempfile.NamedTemporaryFile(以及扩展名tempfile.mkstemp),但是os.mkfifo< /代码> 抛出:

操作系统错误-17:文件已存在

OSError -17:当您在 mkstemp/NamedTemporaryFile 创建的文件上运行该文件时,

How can you create a temporary FIFO (named pipe) in Python? This should work:

import tempfile

temp_file_name = mktemp()
os.mkfifo(temp_file_name)
open(temp_file_name, os.O_WRONLY)
# ... some process, somewhere, will read it ...

However, I'm hesitant because of the big warning in Python Docs 11.6 and potential removal because it's deprecated.

EDIT: It's noteworthy that I've tried tempfile.NamedTemporaryFile (and by extension tempfile.mkstemp), but os.mkfifo throws:

OSError -17: File already exists

when you run it on the files that mkstemp/NamedTemporaryFile have created.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

寄居者 2024-08-12 01:29:38

如果文件已经存在,os.mkfifo() 将失败,并出现异常 OSError: [Errno 17] File isn't,因此这里不存在安全问题。使用 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(如果他们有适当的权限),如果错误/异常处理不当,可能会导致您的程序崩溃。

os.mkfifo() will fail with exception OSError: [Errno 17] File exists if the file already exists, so there is no security issue here. The security issue with using tempfile.mktemp() is the race condition where it is possible for an attacker to create a file with the same name before you open it yourself, but since os.mkfifo() fails if the file already exists this is not a problem.

However, since mktemp() is deprecated you shouldn't use it. You can use tempfile.mkdtemp() instead:

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)

EDIT: I should make it clear that, just because the mktemp() vulnerability is averted by this, there are still the other usual security issues that need to be considered; e.g. an attacker could create the fifo (if they had suitable permissions) before your program did which could cause your program to crash if errors/exceptions are not properly handled.

如痴如狂 2024-08-12 01:29:38

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

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")

You may find it handy to use the following context manager, which creates and removes the temporary file for you:

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

You can use it, for example, like this:

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")
§对你不离不弃 2024-08-12 01:29:38

怎么样使用

d = mkdtemp()
t = os.path.join(d, 'fifo')

How about using

d = mkdtemp()
t = os.path.join(d, 'fifo')
书信已泛黄 2024-08-12 01:29:38

如果它是在您的程序中使用,而不是与任何外部程序一起使用,请查看 队列模块< /a>.作为一个额外的好处,Python 队列是线程安全的。

If it's for use within your program, and not with any externals, have a look at the Queue module. As an added benefit, python queues are thread-safe.

三生殊途 2024-08-12 01:29:38

实际上,mkstemp 所做的就是在循环中运行 mktemp 并不断尝试独占创建,直到成功(请参阅 stdlib 源代码此处)。您可以使用 os.mkfifo 执行相同的操作:

import os, errno, tempfile

def mkftemp(*args, **kwargs):
    for attempt in xrange(1024):
        tpath = tempfile.mktemp(*args, **kwargs)

        try:
            os.mkfifo(tpath, 0600)
        except OSError as e:
            if e.errno == errno.EEXIST:
                # lets try again
                continue
            else:
                raise
        else:
           # NOTE: we only return the path because opening with
           # os.open here would block indefinitely since there 
           # isn't anyone on the other end of the fifo.
           return tpath
    else:
        raise IOError(errno.EEXIST, "No usable temporary file name found")

Effectively, all that mkstemp does is run mktemp in a loop and keeps attempting to exclusively create until it succeeds (see stdlib source code here). You can do the same with os.mkfifo:

import os, errno, tempfile

def mkftemp(*args, **kwargs):
    for attempt in xrange(1024):
        tpath = tempfile.mktemp(*args, **kwargs)

        try:
            os.mkfifo(tpath, 0600)
        except OSError as e:
            if e.errno == errno.EEXIST:
                # lets try again
                continue
            else:
                raise
        else:
           # NOTE: we only return the path because opening with
           # os.open here would block indefinitely since there 
           # isn't anyone on the other end of the fifo.
           return tpath
    else:
        raise IOError(errno.EEXIST, "No usable temporary file name found")
╰つ倒转 2024-08-12 01:29:38

为什么不直接使用 mkstemp()

例如:

import tempfile
import os

handle, filename = tempfile.mkstemp()
os.mkfifo(filename)
writer = open(filename, os.O_WRONLY)
reader = open(filename, os.O_RDONLY)
os.close(handle)

Why not just use mkstemp()?

For example:

import tempfile
import os

handle, filename = tempfile.mkstemp()
os.mkfifo(filename)
writer = open(filename, os.O_WRONLY)
reader = open(filename, os.O_RDONLY)
os.close(handle)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文