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
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 especificarshell=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 deLC_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
bash
era uma casca inchada …os.system
recomendam o uso de .