Momentálně studuji penetrační testování a programování v Pythonu. Chci jen vědět, jak bych provedl příkaz Linuxu v Pythonu. Příkazy, které chci spustit, jsou:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Pokud použiji print v Pythonu a spustit jej v terminálu, udělá to samé jako spuštění, jako kdybyste to sami psali a stiskli Enter ?
Komentáře
Odpověď
Můžete použít os.system() takto:
import os os.system("ls")
Nebo ve vašem případě:
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")
Ještě lépe, můžete použít volání podprocesu, je bezpečnější, výkonnější a pravděpodobně rychlejší:
from subprocess import call call("echo "I like potatos"", shell=True)
Nebo bez vyvolání prostředí:
call(["echo", "I like potatos"])
Pokud chcete zachytit výstup, je jeden způsob, jak to udělat:
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))
Velmi velmi doporučuji nastavit timeout v communicate a také k zachycení výjimek, které můžete při jeho volání získat. Toto je kód velmi náchylný k chybám, takže byste měli počítat s výskytem chyb a podle toho s nimi zacházet.
https://docs.python.org/3/library/subprocess.html
Komentáře
- os.system je od verze 2.6 zastaralý. Správným modulem je podproces.
- @binarysubstrate, zastaralé jako v nepodporované nebo nedostupné? ' Nedávno jsem pracoval na stroji s verzí 2.7 (ne podle volby) a
os.systemstále funguje. - Pokud také používáte
subprocess.callpodle doporučení, možná budete muset zadatshell=True… viz zde - U Pythonu 3.4 je třeba zadat shell = True, jinak nebude příkaz call fungovat. Ve výchozím nastavení se volání pokusí otevřít soubor určený řetězcem, pokud není nastaven shell = True. Také to vypadá, že v Pythonu 3.5 je volání nahrazeno spuštěním
- Obecný POSIX kód by měl pravděpodobně volat
decode()se znakovou sadou zLC_CTYPEproměnná prostředí.
Odpověď
První příkaz jednoduše zapíše do souboru. Neprovedete to jako příkaz prostředí, protože python umí číst a zapisovat do souborů bez pomoci prostředí:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Příkaz iptables je něco, co možná budete chtít provést externě. Nejlepším způsobem je použít modul podprocesu .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Všimněte si, že tato metoda také nepoužívá prostředí, což je zbytečná režie.
Odpověď
Nejrychlejší způsob:
import os os.system("your command here")
Nejedná se o nejpružnější přístup ; pokud potřebujete nad svým procesem větší kontrolu než „spustit jej jednou, do dokončení a blokovat, dokud se neukončí“, měli byste místo toho použít modul subprocess.
Odpověď
Obecně platí, že pokud je to možné, měli byste lépe používat vazby pythonu (mimo jiné lepší chytání výjimek.)
U příkazu echo je samozřejmě lepší použít k zápisu do souboru python, jak je navrženo v odpovědi @jordanm.
Pro iptables příkaz, možná python-iptables ( stránka PyPi , Stránka GitHub s popisem a dokumentem ) by poskytla to, co potřebujete (nekontroloval jsem váš konkrétní příkaz).
Díky tomu byste byli závislí na externí lib, takže musíte vážit výhody. Použití podprocesu funguje, ale pokud chcete použít výstup, budete jej muset sami analyzovat a vypořádat se se změnami výstupu v budoucích verzích iptables.
Komentáře
- Další věc, kterou je třeba si uvědomit, je, že kód testování jednotky s
subprocesshovory je méně užitečný. Ano, můžete si vysmívat volání, ale testy musí vycházet z předpokladů o výsledcích externích hovorů. - Vaše odpověď je spíše jako rada. OP se konkrétně zeptal, jak může spustit systémový příkaz linuxu z pythonu.
- @kapad Ano, ale také upřesnil, proč to chce udělat, a já jsem navrhl alternativu.
Odpověď
Pythonová verze vašeho prostředí. Buďte opatrní, netestoval jsem to.
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
Komentáře
- Rozdělení řetězců funguje pouze pro jednoduché případy. Pro dělení příkazů ve stylu shellu použijte
shlex.split
odpověď
Pokud chcete po SSH spustit tento příkaz v nějakém jiném systému, možná budete muset použít modul s názvem Paramiko. Je to opravdu užitečné.
Pokud je nutné provést příkaz z místního počítače, budou užitečné funkce modulu OS.
Domovská stránka: https://www.paramiko.org/
bashbyla nafouklá skořápka …os.systemdoporučují použítsubprocessmodul.