Se você utiliza o sistema operacional Linux, certamente aprecia a versatilidade dos comandos do terminal.
Ao trabalhar com a linguagem Python, é comum buscar formas de automatizar tarefas, o que economiza tempo e esforço. É possível também utilizar scripts Bash para essa finalidade.
No entanto, Python se destaca na criação de scripts, oferecendo maior facilidade de gerenciamento e manutenção em comparação com Bash, especialmente em projetos maiores.
Mas surge a questão: como executar scripts Bash já existentes usando Python?
Existe uma maneira de integrar a execução de comandos e scripts Bash diretamente em scripts Python?
A resposta é sim! Python possui um módulo integrado chamado `subprocess` que permite executar comandos e scripts dentro de seus scripts. Vamos explorar em detalhes como realizar essa integração.
Executando Comandos Bash com Python
O módulo `subprocess` é a chave para a execução de comandos e scripts Bash. Ele oferece diversos métodos e classes para diferentes cenários.
As principais ferramentas dentro do módulo `subprocess` são o método `run()` e a classe `Popen`. Ambos facilitam a execução de comandos Bash em scripts Python. Vamos analisar cada um deles.
`subprocess.run()`
O método `subprocess.run()` recebe uma lista de strings como argumento posicional. O primeiro elemento dessa lista é o comando Bash a ser executado e os demais são os argumentos do comando.
A seguir, um exemplo simples:
import subprocess subprocess.run(["ls"])
Este script lista todos os arquivos e diretórios presentes no diretório de trabalho atual. Observe que não há argumentos adicionais ao comando `ls`. Podemos adicionar argumentos como `-l`, `-a` ou `-la` para modificar o comportamento do comando.
Veja um exemplo com argumentos:
import subprocess subprocess.run(["ls", "-la"])
Este comando exibe todos os arquivos, incluindo os ocultos, juntamente com suas permissões. O argumento `-la` combina os efeitos de `-l` (listagem detalhada) e `-a` (incluir arquivos ocultos).
Ao escrever comandos, é possível cometer erros. Para capturá-los e tratá-los, podemos usar o argumento de palavra-chave `stderr`.
Acompanhe o exemplo abaixo:
import subprocess result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True) print(result.stderr)
Certifique-se de que o arquivo “sample.txt” não exista no diretório de trabalho. O valor `subprocess.PIPE` para `stderr` direciona a saída de erro para um objeto, que pode ser acessado posteriormente. O argumento `text=True` assegura que a saída seja tratada como uma string.
Da mesma forma, podemos capturar a saída padrão de um comando utilizando o argumento de palavra-chave `stdout`:
import subprocess result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) print(result.stdout)
`subprocess.run()` – Fornecendo Entrada
É possível enviar dados para um comando usando o argumento de palavra-chave `input`. Os dados devem ser fornecidos como uma string. Por isso, é importante definir o argumento `text` como `True`. Por padrão, a entrada é tratada como bytes.
Veja o exemplo:
import subprocess subprocess.run(["python3", "add.py"], text=True, input="2 3")
Neste caso, o script Python “add.py” recebe os números 2 e 3 como entrada por meio do argumento `input`.
`subprocess.Popen()`
A classe `subprocess.Popen()` oferece recursos mais avançados do que o método `subprocess.run()`. Ela permite um controle mais granular da execução dos comandos, incluindo o status, a captura de saídas e o envio de entradas.
Vamos criar uma instância de `subprocess.Popen()` e explorar seus métodos.
`wait()`
O método `wait()` bloqueia a execução do script Python até que o comando especificado seja concluído. As próximas linhas de código só serão executadas após a finalização do comando anterior. Observe este exemplo:
import subprocess process = subprocess.Popen(["ls", "-la"]) print("Concluído!")
Ao executar este código, você notará que a mensagem “Concluído!” é exibida antes da execução do comando `ls`. Para que o script espere o comando terminar antes de imprimir a mensagem, use o método `wait()`:
import subprocess process = subprocess.Popen(["ls", "-la"]) process.wait() print("Concluído!")
Agora, a mensagem será exibida somente após a execução do comando `ls`.
`communicate()`
O método `communicate()` permite obter a saída padrão, a saída de erro e enviar dados de entrada para o comando. Ele retorna uma tupla contendo a saída padrão e a saída de erro, respectivamente. Veja um exemplo:
import subprocess process = subprocess.Popen(["echo", "Olá, Mundo!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) result = process.communicate() print(result)
`subprocess.Popen()` – Fornecendo Entrada
Diferentemente do `subprocess.run()`, a classe `Popen` requer o uso do argumento de palavra-chave `stdin` para fornecer entrada ao comando. A instância da classe `Popen` fornecerá o objeto `stdin`. O método `write()` deste objeto é usado para enviar os dados de entrada.
Lembre-se de que, por padrão, a entrada é tratada como bytes. Portanto, defina `text=True` ao criar a instância de `Popen`.
Exemplo:
import subprocess process = subprocess.Popen(["python3", "add.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) process.stdin.write("2 3") process.stdin.close() print(process.stdout.read())
`poll()`
O método `poll()` verifica se a execução do comando foi concluída. Ele retorna `None` se o comando ainda estiver em execução. Acompanhe o exemplo:
import subprocess process = subprocess.Popen(['ping', '-c 5', 'google.com'], stdout=subprocess.PIPE, text=True) while True: output = process.stdout.readline() if output: print(output.strip()) result = process.poll() if result is not None: break
Neste código, usamos o comando `ping` com 5 requisições. O loop `while` executa até que o comando seja concluído. O método `poll()` verifica o status da execução, retornando um código diferente de `None` quando o comando é finalizado. Isso encerra o loop.
Executando Scripts Bash
Exploramos duas formas de executar comandos. Agora, vamos aprender como executar scripts Bash dentro de scripts Python.
O módulo `subprocess` possui um método chamado `call()`, utilizado para executar scripts Bash. Este método retorna o código de saída do script Bash. O código de saída padrão para scripts Bash é 0.
Crie um script Bash chamado “practice.sh” com o seguinte conteúdo:
#!/bin/bash echo "Olá, Mundo!" exit 1
Agora, crie um script Python para executar o script Bash:
import subprocess exit_code = subprocess.call('./practice.sh') print(exit_code)
Ao executar este script Python, você verá a seguinte saída:
Olá, Mundo! 1
Conclusão
Este artigo abordou a execução de comandos e scripts Bash usando Python. Essas ferramentas são úteis para automatizar tarefas de forma mais eficiente.
Bons estudos e boa codificação!