подпроцесс: запись в один входной канал из разных мест - PullRequest
0 голосов
/ 02 сентября 2018

У меня есть настройка, в которой у меня есть один подпроцесс, в который я хочу чередовать текст через stdin с чередованием, как из Python, так и из другого подпроцесса, в определенном порядке, например так (shell = True используется только для сделать пример проще для написания):

import subprocess

if __name__ == '__main__':
    # only for testing/MWE:
    subprocess.run('echo "sdlfksldf" > bla', shell = True)
    subprocess.run('echo "werwerwerwoeiruwoe" > bla1', shell = True)

    # This is the relevant part; 
    # cat'ing into foo here is just an example for the kind of process I have
    # (actually, it's pdflatex).
    proc = subprocess.Popen(['cat > foo'], stdin = subprocess.PIPE,
                            shell = True, encoding = 'utf-8')
    proc.stdin.write('123') # 1
    proc.stdin.flush()
    subprocess.run(['cat', 'bla', 'bla1'], stdout = proc.stdin) #2 
    proc.stdin.write('456') # 3

Файлы bla и bla1 просто содержат какой-то другой текст, который нужно поместить между строками, сгенерированными в Python. Это работает и создает файл foo, содержащий

123sdlfksldf
werwerwerwoeiruwoe
456

Но мне интересно, так ли это на самом деле? Примечания к сведению:

  • Я использовал stdin.write вместо communicate в # 1 и # 3, хотя последнее рекомендуется в документах, поскольку communicate завершает proc, что не то, что я хочу - я ' я еще не закончил писать.
  • С другой стороны, без flush() другой процесс в # 2 заканчивается первым, и я получаю sdlfksldf\nwerwerwerwoeiruwoe\n123456. Но это выглядит немного странно.
  • Процесс в # 2 действительно cat. Его целью является добавление большого количества существующих файлов к входным данным, что, как я думал, будет более эффективным, чем открытие и write(read()) все через цикл в Python, хотя это решит проблему сброса (только один процесс будет участвует).

Короче говоря, я не знаю, знаю ли я, что я делаю ... Это разумный и надежный способ достижения моей цели? Есть проблемы с буферизацией или блокировкой?

(И если ответ на третий пункт «использовать цикл», все равно остается вопрос о том, что делать, если бы это было не просто cat и его можно было бы избежать.)


Подводя итог, что должна делать настоящая программа: я использую pdflatex при первом вызове Popen вместо cat > foo, читая из stdin. Сначала я генерирую LaTeX на Python и записываю его на вход; затем я добавляю много контента из существующих файлов; и затем я создаю еще один LaTeX на Python, который также будет добавлен.

...