Como obter o código de saída ao usar o método de comunicação por subprocesso do Python?


186

Como recupero o código de saída ao usar o subprocessmódulo e o communicate()método do Python ?

Código relevante:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

Eu deveria estar fazendo isso de outra maneira?

Respostas:


266

Popen.communicateirá definir o returncodeatributo quando terminar (*). Aqui está a seção de documentação relevante:

Popen.returncode 
  The child return code, set by poll() and wait() (and indirectly by communicate()). 
  A None value indicates that the process hasnt terminated yet.

  A negative value -N indicates that the child was terminated by signal N (Unix only).

Então você pode fazer (eu não testei, mas deve funcionar):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*) Isso acontece devido à maneira como é implementado: depois de configurar os threads para ler os fluxos da criança, basta chamar wait.


34
Este exemplo me ajudou, mas seria bom se os exemplos não fizessem o padrão "import subprocess as sp" de importar algo padrão como uma abreviação obscura. Embora isso elimine 8 caracteres do código a seguir, também dificulta a compreensão e a reutilização.
Ublycoyote # 19/16

16
@uglycoyote Não existe uma regra que diga que você deve copiar e colar. Basta redigitá-lo como quiser, são 4 linhas iguais.
Jason C #

5
@uglycoyote você também pode editar-lo para ser algo como from subprocess import Popene, em seguida, é só usar Popenem vez de subprocess(or sp).Popenque eu diria que provavelmente aumenta a legibilidade e encurta linhas
Mitch

2
Sim ... deve ligar process.communicate()e depois atribuir returncodea alguma variável. Se a atribuição for feita antes da chamada communicate, é None.
WesternGun

1
É possível mostrar o código de retorno sem redirecionar o canal? Eu estou chamando um código bash e eu gostaria de ver a saída em tempo real no terminal
Nisba

10

Você deve primeiro verificar se o processo concluiu a execução e se o código de retorno foi lido usando o .waitmétodo Isso retornará o código. Se você quiser acessar mais tarde, ele será armazenado como .returncodeno Popenobjeto.


24
.communicate()já aguarda a finalização do subprocesso.
Caracol mecânico

8

.poll() atualizará o código de retorno.

Experimentar

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

Além disso, depois de .poll()chamado, o código de retorno está disponível no objeto como child.returncode.


quando eu fiz isso .poll () estava vazio. Eu tive que executar child.communicate () na linha acima child.poll () para que isso funcionasse.
NateW

1
Eu acho que você pretendia usar .wait () em vez de .poll (), conforme a documentação: docs.python.org/3/library/subprocess.html . Observe que .wait () usa um parâmetro de tempo limite opcional que pode ser conveniente.
gg99 12/03/19


1

Isso funcionou para mim. Também imprime a saída retornada pelo processo filho

child = subprocess.Popen(serial_script_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retValRunJobsSerialScript = 0
    for line in child.stdout.readlines():
        child.wait()
        print line           
    retValRunJobsSerialScript= child.returncode
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.