代码之家  ›  专栏  ›  技术社区  ›  Brian M. Hunt

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

  •  24
  • Brian M. Hunt  · 技术社区  · 16 年前

    如何在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 抛出:

    OSError-17:文件已存在

    在mkstemp/namedtemporaryfile创建的文件上运行时。

    6 回复  |  直到 6 年前
        1
  •  25
  •   Jonathan Leffler    10 年前

    os.mkfifo() 将异常失败 OSError: [Errno 17] File exists 如果文件已经存在,那么这里没有安全问题。使用时的安全问题 tempfile.mktemp() 在您自己打开文件之前,攻击者是否有可能创建具有相同名称的文件,但由于 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)
    

    编辑:我应该说清楚,只是因为 市场温度() 通过这种方式可以避免漏洞,还需要考虑其他常见的安全问题;例如,攻击者可以在程序执行之前创建FIFO(如果他们具有适当的权限),如果错误/异常处理不当,则可能导致程序崩溃。

        2
  •  3
  •   brendan    16 年前

    如何使用

    d = mkdtemp()
    t = os.path.join(d, 'fifo')
    
        3
  •  3
  •   nilamo    16 年前

    如果它是在程序中使用的,而不是与任何外部的一起使用,请看 Queue module .另外一个好处是,python队列是线程安全的。

        4
  •  1
  •   eestrada    10 年前

    实际上,所有这些 mkstemp 是否运行 mktemp 在循环中,并一直尝试以独占方式创建,直到成功为止(请参见stdlib源代码 here )你也可以这么做 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")
    
        5
  •  1
  •   nirvana-msu    6 年前

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

    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
    

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

    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")
    
        6
  •  -1
  •   Daniel Pryden    16 年前

    为什么不只用 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)