Execute comandos shell em Python

Atualmente, estou estudando teste de penetração e programação Python. Só quero saber como executaria um comando do Linux em Python. Os comandos que desejo executar são:

echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080 

Se eu apenas usar print em Python e executá-lo no terminal fará o mesmo que executá-lo como se você estivesse digitando e pressionando Enter ?

Comentários

  • os.system pode fazer isso.
  • e eu pensei bash era uma casca inchada …
  • Os documentos de os.system recomendam o uso de .
  • Você precisa da saída do iptables?
  • Esta questão deve ser migrada para Stackoverflow.

Resposta

Você pode usar os.system(), assim:

import os os.system("ls") 

Ou no seu caso:

os.system("echo 1 > /proc/sys/net/ipv4/ip_forward") os.system("iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080") 

Melhor ainda, você pode usar a chamada do subprocesso, é mais seguro, mais poderoso e provavelmente mais rápido:

from subprocess import call call("echo "I like potatos"", shell=True) 

Ou, sem invocar o shell:

call(["echo", "I like potatos"]) 

Se você deseja capturar a saída, uma maneira de fazer é assim:

import subprocess cmd = ["echo", "I like potatos"] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) o, e = proc.communicate() print("Output: " + o.decode("ascii")) print("Error: " + e.decode("ascii")) print("code: " + str(proc.returncode)) 

Eu altamente recomendo definir um timeout em communicate, e também para capturar as exceções que você pode obter ao chamá-lo. Este é um código muito sujeito a erros, então você deve esperar que os erros aconteçam e lidar com eles de acordo.

https://docs.python.org/3/library/subprocess.html

Comentários

  • os.system está obsoleto desde a versão 2.6. Subprocesso é o módulo certo para usar.
  • @binarysubstrate, obsoleto porque não é compatível ou não está disponível? Eu ‘ estive trabalhando recentemente na máquina com 2.7 (não por opção) e os.system ainda funciona.
  • Além disso, se estiver usando subprocess.call conforme recomendado, pode ser necessário especificar shell=True … consulte aqui
  • Com Python 3.4, o shell = True deve ser declarado, caso contrário, o comando de chamada não funcionará. Por padrão, a chamada tentará abrir um arquivo especificado pela string, a menos que shell = True seja definido. Também parece que no Python 3.5, a chamada foi substituída por run
  • O código POSIX genérico provavelmente deve chamar decode() com charset de LC_CTYPE variável de ambiente.

Resposta

O primeiro comando simplesmente grava em um arquivo. Você não executaria isso como um comando shell porque python pode ler e gravar arquivos sem a ajuda de um shell:

with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1") 

O comando iptables é algo que você pode querer executar externamente. A melhor maneira de fazer isso é usar o módulo de subprocesso .

import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"]) 

Observe que este método também não usa um shell, o que é uma sobrecarga desnecessária.

Resposta

A maneira mais rápida:

import os os.system("your command here") 

Esta não é a abordagem mais flexível ; se precisar de mais controle sobre o processo do que “execute-o uma vez, até a conclusão e bloqueie até que ele saia”, então você deve usar o módulo subprocess.

Resposta

Como regra geral, é melhor usar ligações python sempre que possível (melhor captura de exceções, entre outras vantagens.)

Para o comando echo, é obviamente melhor usar python para escrever no arquivo, conforme sugerido na resposta de @jordanm.

Para o iptables comando, talvez python-iptables ( página PyPi , página do GitHub com descrição e documento ) forneceria o que você precisa (não verifiquei seu comando específico).

Isso faria você depender de um lib externo, então você tem que pesar os benefícios. Usar o subprocesso funciona, mas se você quiser usar a saída, terá que analisá-la você mesmo e lidar com as alterações na saída em iptables versões futuras.

Comentários

  • Outra coisa a observar é que o código de teste de unidade com subprocess chamadas é menos útil. Sim, você pode simular o chamadas, mas os testes têm que fazer suposições sobre os resultados das chamadas externas.
  • Sua resposta é mais como um conselho. O OP perguntou especificamente como ele pode executar um comando do sistema Linux a partir de python.
  • @kapad Sim, mas ele também especificou por que queria fazer isso e eu propus uma alternativa.

Resposta

Uma versão python do seu shell. Tenha cuidado, eu não testei.

from subprocess import run def bash(command): run(command.split()) >>> bash("find / -name null") /dev/null /sys/fs/selinux/null /sys/devices/virtual/mem/null /sys/class/mem/null /usr/lib/kbd/consoletrans/null 

Comentários

  • A divisão de strings só funciona para casos simples. Para divisão de comando no estilo shell, use shlex.split

Resposta

Se você deseja executar este comando em algum outro sistema após o SSH, pode ser necessário usar o módulo denominado Paramiko. É realmente útil.

Se a execução do comando tiver que ser feita na máquina local, as funções do módulo os serão úteis.

Página inicial: https://www.paramiko.org/

Desenvolvimento: https://github.com/paramiko/paramiko

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *