O módulo Python subprocess permite que você acione, execute e avalie programas externos dentro do seu código. Suas duas funções mais im­por­tan­tes são run() e popen().

O que é Python subprocess?

O módulo Python subprocess faz parte da bi­bli­o­teca padrão dessa linguagem de pro­gra­ma­ção desde a versão 2.4. Trata-se de uma fer­ra­menta poderosa e abran­gente que pode ser usada para executar outros programas ou comandos dentro de um código. Além de iniciar programas, você também pode controlar e ajustar o fluxo dos dados. Python subprocess oferece vários métodos e funções. Os mais im­por­tan­tes serão apre­sen­ta­dos com exemplos práticos neste artigo.

Python subprocess com run()

Antes de co­me­çar­mos, é im­por­tante que você entenda a estrutura e o fun­ci­o­na­mento básico do Python subprocess. O módulo é utilizado para executar sub­pro­ces­sos, atuando como o processo pai que cria um processo filho. A função mais fre­quen­te­mente usada dentro do módulo é run(), que inicia um processo e segue com os próximos passos apenas quando este processo for concluído.

Exemplo de Python subprocess com run()

Agora, vamos aplicar essa função a um exemplo simples para entender o fun­ci­o­na­mento do Python subprocess. Primeiro, im­por­ta­mos os módulos subprocess e sys e, em seguida, exe­cu­ta­mos um comando simples. O código é:

import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "print('oi')"])
python

A saída será:

oi
python
  • subprocess.run: A função principal, que recebe uma lista com strings que contêm o comando a ser executado. Em Python, run() inicia um novo programa.
  • sys.executable: Caminho absoluto do in­ter­pre­ta­dor Python que foi usado para executar o programa. Um exemplo de caminho é /local/usuario/bin/exemplo.
  • -c: Opção de linha de comando que indica que a string fornecida deve ser executada. Neste exemplo, trata-se de um programa que imprime a palavra “oi”.

Executar script com Python subprocess

Para testar como utilizar o módulo com um script próprio, ex­pe­ri­mente replicar este nosso exemplo. Primeiro, crie um script simples no formato .py e salve-o como “exem­plos­cript.py”:

print("Hoje o tempo está bom")
python

Para executar este arquivo com Python subprocess, utilize o código abaixo:

import subprocess
result = subprocess.run(["python", "exemploscript.py"], capture_output=True, text=True)
print(result.stdout)
python

A saída cor­res­pon­dente será:

Hoje o tempo está bom
python

Abrir programas externos com Python subprocess

Com o Python subprocess e a função run(), é possível abrir qualquer programa. A única exigência é conhecer o nome exato do programa ou seu caminho no sistema. No exemplo abaixo, co­man­da­mos a ini­ci­a­li­za­ção do Bloco de Notas:

import subprocess
subprocess.run(["notepad.exe"])
python

CompletedProcess para captura de saídas externas

Agora, tente capturar uma saída externa. Execute um programa externo usando Python subprocess como de­mons­trado an­te­ri­or­mente. Desta vez, um objeto CompletedProcess será retornado. Nós já fizemos os ajustes ne­ces­sá­rios no nosso exemplo e agora vamos explorá-los em mais detalhes. Começamos novamente com nosso código inicial, mas desta vez vamos modificá-lo.

import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "print('oi')"], capture_output=True, text=True)
print("A saída padrão é:", result.stdout)
print("O erro padrão é:", result.stderr)
python

Aqui, ins­truí­mos o sistema a imprimir “oi” em um processo filho. Os novos ar­gu­men­tos capture_output=True e text=True também são passados para run(). Se o comando for executado sem erros, você obterá um objeto CompletedProcess vinculado ao result. Este objeto contém in­for­ma­ções sobre o código de saída do programa e as transmite para result.stdout e result.stderr. stdout é a saída padrão, enquanto stderr refere-se a possíveis erros padrão. text=True é usado para imprimir a saída como uma string. Como não há erros esperados, o resultado será:

A saída padrão é: oi
 
O erro padrão é:
python

Para ilustrar melhor, vamos criar um exemplo onde stderr não ficará vazio. O código é:

import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "raise ValueError('erro')"], capture_output=True, text=True)
print("A saída padrão é:", result.stdout)
print("O erro padrão é:", result.stderr)
python

Já que a saída padrão permanece vazia, stderr produz:

A saída padrão é: 
O erro padrão é: Traceback (most recent call last):
    File "<string>", line 1, in <module>
ValueError: erro
python

Executar comandos di­re­ta­mente no código

Se você quer incluir um comando di­re­ta­mente no código, o Python subprocess também oferece essa opção. O código seria assim:

import subprocess
result = subprocess.run(["C:/Users/nome/anaconda3/python", "-c", "print('Essa saída foi diretamente incorporada a uma função')"], capture_output=True, text=True, shell=True)
print("A saída padrão é:", result.stdout)
python

A saída será:

A saída padrão é: Essa saída foi diretamente incorporada a uma função
python

Pausar ou encerrar processos com Python subprocess

Outro uso muito útil do Python subprocess é pausar ou encerrar processos usando o argumento timeout jun­ta­mente com run(). Com­bi­na­dos, eles in­ter­rom­pem um programa externo se este demorar demais para ser executado. Para tanto, usamos a função time.sleep. O código cor­res­pon­dente é:

import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "import time; time.sleep(3)"], timeout=1)
python

O processo filho usa time.sleep para pausar por três segundos. No entanto, como o argumento timeout=1, foi definido, o programa será in­ter­rom­pido após um segundo, gerando a exceção TimeoutExpired.

Python subprocess com popen()

Embora run() seja a função mais utilizada do subprocess no Python, existem outras classes im­por­tan­tes que podem ser muito úteis. Uma delas é popen(). Esta classe é a base do subprocess no Python e é um pouco mais complexa do que run(). No entanto, com popen(), você tem mais controle sobre a execução e pode interagir com a entrada e saída. O nome da classe deriva de um comando UNIX e significa “pipe open”.

Quase todos os ar­gu­men­tos que você usa com run() também são per­mi­ti­dos para popen(). Ao contrário de run(), essa função não espera que um processo seja concluído, mas inicia um segundo processo paralelo. Podemos ilustrar o fun­ci­o­na­mento com um exemplo simples:

import subprocess
from time import sleep
def poll_and_read(process):
    print(f"Isto é o que poll() retorna: {process.poll()}")
    print(f"Isto é a saída padrão: {process.stdout.read().decode('utf-8')}")
process = subprocess.Popen(["python", "timer.py", "3"], stdout=subprocess.PIPE)
poll_and_read(process)
sleep(2)
poll_and_read(process)
sleep(2)
poll_and_read(process)
process.wait()
print(f"Código de saída do processo: {process.returncode}")
python

Aqui, uti­li­za­mos o método .poll() para verificar se o processo ainda está em execução ou já foi concluído. Enquanto o processo está em execução, o valor “none” é exibido. Depois, o método retorna o código de saída. Com .read(), todos os bytes que se acu­mu­la­ram até aquele ponto em .stdout são lidos. Ao executar o código, você verá ini­ci­al­mente o valor “none” e, em seguida, o conteúdo de stdout até que o processo seja concluído, quando poll() retornará “0”.

Dica

Faça a im­plan­ta­ção da sua aplicação ou site di­re­ta­mente pelo GitHub: Com o Deploy Now da IONOS, você se beneficia de uma con­fi­gu­ra­ção mais rápida, de fluxos de trabalho oti­mi­za­dos e de maior es­ca­la­bi­li­dade. Encontre o plano certo para as suas ne­ces­si­da­des!

Ir para o menu principal