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.system
stále funguje. - Pokud také používáte
subprocess.call
podle 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_CTYPE
promě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
subprocess
hovory 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/
bash
byla nafouklá skořápka …os.system
doporučují použítsubprocess
modul.