# Python subprocess: Executar comandos e programas externos

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 é:

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

A saída será:

```python
oi
```

- `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”:

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

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

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

A saída correspondente será:

```python
Hoje o tempo está bom
```

## 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:

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

## `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.

```python
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)
```

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á:

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

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

```python
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)
```

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

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

## 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:

```python
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)
```

A saída será:

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

## 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 é:

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

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:

```python
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}")
```

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](https://www.ionos.com/hosting/deploy-now "Deploy Now — IONOS") 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!


This is a markdown version of: [https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/python-subprocess/](https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/python-subprocess/) for AI/LLM consumption.