Como faço para imprimir saídas de chamadas para subprocess.Popen (...) em um loop?

StackOverflow https://stackoverflow.com/questions/714879

  •  23-08-2019
  •  | 
  •  

Pergunta

Eu escrevi um script para executar um programa de linha de comando com diferentes argumentos de entrada e pegar uma determinada linha a partir da saída. Eu tenho o seguinte em execução em um loop:

p1 = subprocess.Popen(["program", args], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(["grep", phrase], stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p = str(p2.stdout.readlines())
print 'p is ', p

Um problema é que só há saída após o loop é running acabado. Quero imprimir algo cada vez que um processo for concluído. Como posso fazer isso?

Além disso, eu quero ter a opção de exibir a saída de p1. Mas eu não posso agarrá-lo com p1.stdout.readlines () sem p2 de ruptura. Como posso fazer isso?

Eu estava pensando que eu não poderia fazer a chamada para grep, armazenar a saída de p1 e procurar a frase, mas não há muita saída, assim desta forma parece bastante ineficiente.

Todas as sugestões seria muito apreciada. Obrigado!

Foi útil?

Solução

Aqui está um corte rápido, que trabalhou para mim em Linux. Ele pode funcionar para você, dependendo de suas necessidades. Ele usa tee como um filtro que, se você passar print_all ao seu roteiro, vai duplicar uma cópia extra para / dev / tty (hey, eu disse isso era um hack):

#!/usr/bin/env python

import subprocess
import sys

phrase = "bar"
if len(sys.argv) > 1 and sys.argv[1] == 'print_all':
    tee_args = ['tee', '/dev/tty']
else:
    tee_args = ['tee']

p1 = subprocess.Popen(["./program"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(tee_args, stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p3 = subprocess.Popen(["grep", phrase], stdin=p2.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p3.wait()
p = str(p3.stdout.readlines())
print 'p is ', p

Com o seguinte como conteúdo para program:

#!/bin/sh

echo foo
echo bar
echo baz

Exemplo de saída:

$ ./foo13.py
p is  ['bar\n']
$ ./foo13.py print_all
foo
bar
baz
p is  ['bar\n']

Outras dicas

Tente chamar sys.stdout.flush () após cada declaração de impressão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top