可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
How about using
d = mkdtemp() t = os.path.join(d, 'fifo')
回答3:
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.
回答4:
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")
回答5:
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)