Создать временный FIFO (именованный канал) в Python?
Как можно создать временный FIFO (именованный канал) в Python? Это должно сработать:
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 и потенциального удаления, потому что он устарел.
EDIT : примечательно, что я пытался tempfile.NamedTemporaryFile (и по расширению tempfile.mkstemp), но os.mkfifo бросает:
OSError -17: файл уже существует
При запуске его в файлах, созданных mkstemp/NamedTemporaryFile.
5 ответов:
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)EDIT: я должен пояснить, что, просто поскольку уязвимость
mktemp()предотвращается этим, все еще существуют другие обычные проблемы безопасности, которые необходимо учитывать; например, злоумышленник может создать fifo (если у него есть соответствующие разрешения) до того, как это сделает ваша программа, что может привести к сбою вашей программы, если ошибки/исключения не будут должным образом обработаны.
Фактически, все, что делает
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")
Почему бы просто не использовать 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)
Comments