Pergunta

Preciso iniciar um processo externo que seja controlado por meio de mensagens enviadas via STDIN e STDOUT. Usando o subprocess.popen, sou capaz de iniciar o processo, mas não consigo controlar a execução via stdin, conforme necessário.

O fluxo do que estou tentando concluir é:

  1. Inicie o processo externo
  2. Itera para um número de etapas
    1. Diga ao processo externo para concluir a próxima etapa de processamento, escrevendo um personagem de nova linha para o seu stdin
    2. Aguarde o processo externo sinalizar, ele concluiu a etapa escrevendo um personagem de nova linha para o seu stdout
  3. Feche o STDIN do processo externo para indicar com o processo externo que a execução foi concluída.

Eu criei o seguinte até agora:

process=subprocess.Popen([PathToProcess],stdin=subprocess.PIPE,stdout=subprocess.PIPE);
for i in xrange(StepsToComplete):
    print "Forcing step # %s"%i
    process.communicate(input='\n')

Quando executo o código acima, o ' n' não é comunicado ao processo externo e nunca vou além da etapa nº 0. O código bloqueia em Process.Communicate () e não prossegue mais. Estou usando o método Communicate () incorretamente?

Além disso, como eu implementaria a funcionalidade "Aguarde até que o processo externo escreva uma nova linha"?

Foi útil?

Solução

Process.Communicate (input = ' n') está errado. Se você perceber nos documentos do Python, ele grava sua corda no stdin da criança, lê toda a saída da criança até que a criança saia. De doc.python.org:

Popen.Communicate (input = Nenhum) Interaja com o processo: Envie dados para Stdin. Leia os dados do stdout e Stderr, até o final do arquivo ser atingido. Aguarde o processo de rescisão do processo. O argumento de entrada opcional deve ser uma string a ser enviada ao processo filho, ou nenhum, se nenhum dado deve ser enviado para a criança.

Em vez disso, você quer apenas escrever para o stdin da criança. Em seguida, leia o seu loop.

Algo mais como:

process=subprocess.Popen([PathToProcess],stdin=subprocess.PIPE,stdout=subprocess.PIPE);
for i in xrange(StepsToComplete):
    print "Forcing step # %s"%i
    process.stdin.write("\n")
    result=process.stdout.readline()

Isso fará algo mais parecido com o que você deseja.

Outras dicas

Você poderia usar Twisted, usando Reactor.spawnProcess e LineReCeiver.

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