Aktualnie uczę się testów penetracyjnych i programowania w Pythonie. Chcę tylko wiedzieć, jak zabrać się za wykonanie polecenia Linuksa w Pythonie. Polecenia, które chcę wykonać to:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Jeśli użyję tylko print
w Pythonie i uruchomi go w terminalu, czy zrobi to samo, co wykonanie go tak, jakbyś sam go wpisywał i naciskając Enter ?
Komentarze
Odpowiedź
Możesz użyć os.system()
, na przykład:
import os os.system("ls")
Lub w twoim przypadku:
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")
Jeszcze lepiej, możesz użyć wywołania podprocesu, jest to bezpieczniejszy, mocniejszy i prawdopodobnie szybszy:
from subprocess import call call("echo "I like potatos"", shell=True)
Lub bez wywoływania powłoki:
call(["echo", "I like potatos"])
Jeśli chcesz przechwycić wynik, możesz to zrobić w następujący sposób:
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))
Bardzo zalecam ustawienie timeout
w communicate
, a także do przechwytywania wyjątków, które można uzyskać, wywołując tę usługę. Jest to kod bardzo podatny na błędy, więc należy spodziewać się błędów i odpowiednio je obsłużyć.
https://docs.python.org/3/library/subprocess.html
Komentarze
- os.system jest przestarzały od wersji 2.6. Podproces jest właściwym modułem.
- @binarysubstrate, przestarzały, ponieważ nie jest obsługiwany lub niedostępny? ' ostatnio pracowałem na komputerze z wersją 2.7 (nie z wyboru) i
os.system
nadal działa. - Ponadto, jeśli używasz
subprocess.call
zgodnie z zaleceniami, może być konieczne określenieshell=True
… patrz tutaj - W Pythonie 3.4 należy podać shell = True, w przeciwnym razie polecenie call nie będzie działać. Domyślnie wywołanie spróbuje otworzyć plik określony przez łańcuch, chyba że ustawiono shell = True. Wygląda również na to, że w Pythonie 3.5 wywołanie jest zastępowane uruchomieniem
- Generyczny kod POSIX powinien prawdopodobnie wywołać
decode()
z zestawem znaków zLC_CTYPE
zmienna środowiskowa.
Odpowiedź
Pierwsze polecenie po prostu zapisuje do pliku. Nie wykonałbyś tego jako polecenia powłoki, ponieważ python
może czytać i zapisywać w plikach bez pomocy powłoki:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Polecenie iptables
to coś, co możesz chcieć wykonać zewnętrznie. Najlepszym sposobem na to jest użycie polecenia moduł podprocesu .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Zauważ, że ta metoda również nie używa powłoki, co jest niepotrzebnym narzutem.
Odpowiedź
Najszybszy sposób:
import os os.system("your command here")
To nie jest najbardziej elastyczne podejście ; jeśli potrzebujesz większej kontroli nad swoim procesem niż „uruchom go raz do końca i blokuj do zakończenia”, powinieneś zamiast tego użyć modułu subprocess
.
Odpowiedź
Zgodnie z ogólną zasadą, lepiej używać powiązań Pythona, gdy tylko jest to możliwe (między innymi lepsze przechwytywanie wyjątków).
W przypadku polecenia echo
oczywiście lepiej jest używać języka Python do zapisu w pliku, zgodnie z sugestią zawartą w odpowiedzi @jordanm.
iptables
polecenie, być może python-iptables
( strona PyPi , Strona GitHub z opisem i dokumentacją ) zapewniłaby to, czego potrzebujesz (nie sprawdzałem twojego konkretnego polecenia).
To sprawiłoby, że polegałeś na biblioteka zewnętrzna, więc musisz zważyć korzyści. Używanie podprocesu działa, ale jeśli chcesz użyć wyniku, będziesz musiał samodzielnie je przeanalizować i zająć się zmianami wyników w przyszłych iptables
wersjach.
Komentarze
- Kolejną rzeczą, na którą należy zwrócić uwagę, jest to, że kod testów jednostkowych z wywołaniami
subprocess
jest mniej przydatny. Tak, możesz wyszydzać wywołań, ale testy muszą przyjmować założenia dotyczące wyników wywołań zewnętrznych. - Twoja odpowiedź jest bardziej podobna do porady. Operator specjalnie zapytał, w jaki sposób może uruchomić polecenie systemu linux z Pythona.
- @kapad Tak, ale sprecyzował również, dlaczego chce to zrobić, a ja zaproponowałem alternatywę.
Odpowiedź
Wersja twojej powłoki w Pythonie. Uważaj, jeszcze jej nie testowałem.
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
Komentarze
- Podział ciągów działa tylko w prostych przypadkach. Do dzielenia poleceń w stylu powłoki użyj
shlex.split
Odpowiedź
Jeśli chcesz wykonać to polecenie w innym systemie po SSH, być może będziesz musiał użyć modułu o nazwie Paramiko. Jest to naprawdę przydatne.
Jeśli wykonanie polecenia ma być wykonane z komputera lokalnego, pomocne będą funkcje modułu os.
Strona główna: https://www.paramiko.org/
Programowanie: https://github.com/paramiko/paramiko
bash
była rozdętą powłoką …os.system
zaleca się używaniesubprocess
.