Como executar comandos do shell em Python usando o método de execução de subprocesso

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess é um módulo Python integrado que pode ser usado para criar novos processos e interagir com seus fluxos de dados de entrada e saída. Em termos mais simples, você pode usá-lo para executar comandos shell e executar binários executáveis ​​geralmente espalhados em várias pastas bin em um sistema de arquivos Linux. Você também pode fornecer um caminho completo para um binário executável e usar qualquer opção de linha de comando associada ao binário. Este artigo explicará como usar o módulo de subprocesso e seu método de execução em aplicativos Python. Todos os exemplos de código no artigo são testados com Python 3.8.2 no Ubuntu 20.04.

O método Subprocess.run

O método Subprocess.run leva uma lista de argumentos. Quando o método é chamado, ele executa o comando e espera a conclusão do processo, retornando um objeto CompletedProcess no final. O objeto CompletedProcess retorna stdout, stderr, argumentos originais usados ​​ao chamar o método e um código de retorno. Stdout se refere ao fluxo de dados produzido pelo comando, enquanto stderr se refere a quaisquer erros levantados durante a execução do programa. Qualquer código de retorno diferente de zero (código de saída) significaria erro com o comando executado no método subprocess.run.







Exemplo 1: Conteúdo de saída de um arquivo de texto usando o método Subprocess.run

O comando a seguir produzirá o conteúdo de um arquivo data.txt, presumindo que ele contenha uma string name = John.



importar subprocesso
subprocesso.corre(['gato', 'data.txt'])

Executar o código acima retornará a seguinte saída:



nome=João
CompletedProcess(args=['gato', 'data.txt'],Código de retorno=0)

O primeiro elemento do argumento da lista é o nome do comando a ser executado. Qualquer elemento na lista que segue o primeiro elemento é considerado opções ou opções de linha de comando. Você também pode usar traço simples e traço duplo para definir as opções. Por exemplo, para listar arquivos e pastas em um diretório, o código seria subprocess.run ([ls, -l]. Na maioria desses casos, você pode considerar qualquer argumento separado por espaço em um comando shell como um elemento individual em a lista fornecida ao método subprocess.run.





Exemplo 2: suprimir a saída do método Subprocess.run

Para suprimir a saída do método subprocess.run, você terá que fornecer stdout = subprocess.DEVNULL e stderr = subprocess.DEVNULL como argumentos adicionais.

importar subprocesso

subprocesso.corre(['gato', 'data.txt'],stdout=subprocesso.DEVNULL,
stderr=subprocesso.DEVNULL)

Executar o código acima produzirá a seguinte saída:



CompletedProcess (args = ['cat', 'data.txt'], returncode = 0)

Exemplo 3: Captura de saída do método Subprocess.run

Para capturar a saída do método subprocess.run, use um argumento adicional denominado capture_output = True.

importar subprocesso
saída= subprocesso.corre(['gato', 'data.txt'],capture_output=Verdade)
imprimir (saída)

Executar o código acima produzirá a seguinte saída:

CompletedProcess(args=['gato', 'data.txt'],Código de retorno=0,
stdout=b'nome = John n',stderr=b'')

Você pode acessar individualmente os valores stdout e stderr usando os métodos output.stdout e output.stderr. A saída é produzida como uma sequência de bytes. Para obter uma string como saída, use o método output.stdout.decode (utf-8). Você também pode fornecer text = True como um argumento extra para a chamada subprocess.run para obter a saída no formato de string. Para obter o código de status de saída, você pode usar o método output.returncode.

Exemplo 4: Gerar exceção na falha de comando executado pelo método Subprocess.run

Para levantar uma exceção quando o comando sai com um status diferente de zero, use o argumento check = True.

importar subprocesso
subprocesso.corre(['gato', 'data.tx'],capture_output=Verdade,texto=Verdade,Verifica=Verdade)

Executar o código acima produzirá a seguinte saída:

aumentar CalledProcessError (retcode, process.args,
subprocess.CalledProcessError: Comando '[' cat ',' data.tx ']'
retornou status de saída diferente de zero 1.

Exemplo 5: passar uma string para um comando executado pelo método Subprocess.run

Você pode passar uma string para o comando a ser executado pelo método subprocess.run usando o argumento input = 'string'.

importar subprocesso
saída= subprocesso.corre(['gato'], entrada='data.txt',capture_output=Verdade,
texto=Verdade,Verifica=Verdade)
imprimir (saída)

Executar o código acima produzirá a seguinte saída:

CompletedProcess (args = ['cat'], returncode = 0, stdout = 'data.txt', stderr = '')

Como você pode ver, o código acima passa data.txt como uma string e não como um objeto de arquivo. Para passar data.txt como um arquivo, use o argumento stdin.

com abrir('data.txt') Comof:
saída= subprocesso.corre(['gato'],Stdin=f,capture_output=Verdade,
texto=Verdade,Verifica=Verdade)
imprimir (saída)

Executar o código acima produzirá a seguinte saída:

CompletedProcess (args = ['cat'], returncode = 0, stdout = 'name = John n', stderr = '')

Exemplo 6: execute o comando diretamente no shell usando o método Subprocess.run

É possível executar um comando diretamente no shell no estado em que se encontra, em vez de usar uma string dividida no comando principal e nas opções que o seguem. Para fazer isso, você deve passar shell = True como um argumento adicional. No entanto, isso é desencorajado pelos desenvolvedores de python, pois o uso de shell = True pode levar a problemas de segurança. Você pode ler mais sobre as implicações de segurança em aqui .

importar subprocesso
subprocesso.corre('cat' data.txt '',Concha=Verdade)

Executar o código acima produzirá a seguinte saída:

nome = John

Conclusão

O método subprocess.run em Python é muito poderoso, pois permite que você execute comandos shell dentro do próprio Python. Isso ajuda a limitar todo o código ao próprio Python sem a necessidade de ter código de script de shell adicional em arquivos separados. Pode ser, no entanto, bastante complicado tokenizar corretamente os comandos do shell em uma lista python. Você pode usar o método shlex.split () para tokenizar comandos shell simples, mas em comandos longos e complexos - especialmente aqueles com símbolos de barra vertical - shlex falha em dividir o comando corretamente. Nesses casos, a depuração pode ser um problema complicado. Você pode usar o argumento shell = True para evitar isso, mas existem certas questões de segurança associadas a esta ação.