Attualmente sto studiando test di penetrazione e programmazione Python. Voglio solo sapere come posso eseguire un comando Linux in Python. I comandi che voglio eseguire sono:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Se uso solo print
in Python ed eseguirlo nel terminale farà lo stesso che eseguirlo come se lo stessi digitando e premendo Invio ?
Commenti
Risposta
Puoi utilizzare os.system()
in questo modo:
import os os.system("ls")
O nel tuo 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")
Meglio ancora, puoi usare la chiamata del sottoprocesso, è più sicuro, più potente e probabilmente più veloce:
from subprocess import call call("echo "I like potatos"", shell=True)
Oppure, senza richiamare la shell:
call(["echo", "I like potatos"])
Se vuoi catturare loutput, un modo per farlo è questo:
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))
altamente consiglio di impostare un timeout
in communicate
e anche per catturare le eccezioni che puoi ottenere quando lo chiami. Questo è un codice molto soggetto a errori, quindi dovresti aspettarti che si verifichino errori e gestirli di conseguenza.
https://docs.python.org/3/library/subprocess.html
Commenti
- os.system è deprecato dalla versione 2.6. Subprocess è il modulo giusto da usare.
- @binarysubstrate, deprecato perché non supportato o non disponibile? ‘ ho lavorato di recente su una macchina con 2.7 (non per scelta) e
os.system
funziona ancora. - Inoltre, se utilizzi
subprocess.call
come consigliato, potresti dover specificareshell=True
… consulta qui - Con Python 3.4 deve essere dichiarato shell = True altrimenti il comando call non funzionerà. Per impostazione predefinita, call proverà ad aprire un file specificato dalla stringa a meno che non sia impostato shell = True. Sembra anche che in Python 3.5 la chiamata sia sostituita con run
- Il codice POSIX generico dovrebbe probabilmente chiamare
decode()
con il set di caratteri daLC_CTYPE
variabile dambiente.
Risposta
Il primo comando scrive semplicemente su un file. Non lo eseguiresti come comando di shell perché python
può leggere e scrivere su file senza laiuto di una shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Il comando iptables
è qualcosa che potresti voler eseguire esternamente. Il modo migliore per farlo è utilizzare modulo sottoprocesso .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Nota che anche questo metodo non utilizza una shell, il che è un sovraccarico non necessario.
Risposta
Il modo più veloce:
import os os.system("your command here")
Questo non è lapproccio più flessibile ; se hai bisogno di un maggiore controllo sul tuo processo rispetto a “eseguilo una volta, fino al completamento e bloccalo finché non esce”, allora dovresti usare il modulo subprocess
.
Risposta
Come regola generale, “faresti meglio a usare i collegamenti python quando possibile (migliore rilevamento delle eccezioni, tra gli altri vantaggi).
Per il comando echo
, è ovviamente meglio usare python per scrivere nel file come suggerito nella risposta di @jordanm.
Per il iptables
comando, forse python-iptables
( PyPi page , pagina GitHub con descrizione e documento ) fornirebbe ciò di cui hai bisogno (non ho controllato il tuo comando specifico).
Ciò ti farebbe dipendere da un lib esterno, quindi devi valutare i benefici. Luso del sottoprocesso funziona, ma se vuoi usare loutput, dovrai analizzarlo da solo e gestire le modifiche alloutput nelle versioni iptables
future.
Commenti
- Unaltra cosa da notare è che il codice di unit test con chiamate
subprocess
è meno utile. Sì, puoi deridere il chiamate, ma i test devono fare ipotesi sui risultati delle chiamate esterne. - La tua risposta è più simile a un consiglio. LOP ha chiesto specificatamente come può eseguire un comando di sistema Linux da python.
- @kapad Sì, ma ha anche specificato perché voleva farlo e ho proposto unalternativa.
Risposta
Una versione python della tua shell. Fai attenzione, non lho provata.
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
Commenti
- La suddivisione delle stringhe funziona solo per i casi semplici. Per la suddivisione dei comandi in stile shell usa
shlex.split
Answer
Se si desidera eseguire questo comando in un altro sistema dopo SSH, potrebbe essere necessario utilizzare il modulo denominato Paramiko. È davvero utile.
Se lesecuzione del comando deve essere eseguita dalla macchina locale, le funzioni del modulo os saranno utili.
Home page: https://www.paramiko.org/
Sviluppo: https://github.com/paramiko/paramiko
bash
era un guscio gonfio …os.system
consiglia di utilizzaresubprocess
module.