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

O que é Python subprocess?

O módulo Python subprocess faz parte da biblioteca padrão dessa linguagem de programação desde a versão 2.4. Trata-se de uma ferramenta poderosa e abrangente 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 importantes serão apresentados com exemplos práticos neste artigo.

Python subprocess com run()

Antes de começarmos, é importante que você entenda a estrutura e o funcionamento básico do Python subprocess. O módulo é utilizado para executar subprocessos, atuando como o processo pai que cria um processo filho. A função mais frequentemente 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 funcionamento do Python subprocess. Primeiro, importamos os módulos subprocess e sys e, em seguida, executamos 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 interpretador 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, experimente replicar este nosso exemplo. Primeiro, crie um script simples no formato .py e salve-o como “exemploscript.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 correspondente 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, comandamos a inicializaçã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 demonstrado anteriormente. Desta vez, um objeto CompletedProcess será retornado. Nós já fizemos os ajustes necessá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, instruímos o sistema a imprimir “oi” em um processo filho. Os novos argumentos 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 informaçõ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 diretamente no código

Se você quer incluir um comando diretamente 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 juntamente com run(). Combinados, eles interrompem um programa externo se este demorar demais para ser executado. Para tanto, usamos a função time.sleep. O código correspondente é:

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á interrompido 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 importantes 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 argumentos que você usa com run() também são permitidos 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 funcionamento 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, utilizamos 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 acumularam até aquele ponto em .stdout são lidos. Ao executar o código, você verá inicialmente 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 implantação da sua aplicação ou site diretamente pelo GitHub: Com o Deploy Now da IONOS, você se beneficia de uma configuração mais rápida, de fluxos de trabalho otimizados e de maior escalabilidade. Encontre o plano certo para as suas necessidades!

Este artigo foi útil?
Ir para o menu principal