Создать временный 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 и потенциальное удаление, потому что оно устарело.
редактировать: примечательно, что я пробовал 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)
ИЗМЕНИТЬ: I должно быть ясно, что, просто потому, что mktemp()
уязвимость предотвращается этим, есть еще другие обычные проблемы безопасности, которые необходимо учитывать; например, злоумышленник может создать fifo (если у них есть подходящие разрешения) до вашей программы, что может привести к сбою вашей программы, если ошибки/исключения не обрабатываются должным образом.
Если это для использования в вашей программе, а не с какими-либо внешними, посмотрите на модуль очереди. В качестве дополнительного преимущества очереди python являются потокобезопасными.
эффективно, все это mkstemp
does is run 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)