Wykonywanie poleceń powłoki w Pythonie

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

  • os.system może to zrobić.
  • i pomyślałem bash była rozdętą powłoką …
  • W dokumentach dla os.system zaleca się używanie subprocess.
  • Czy potrzebujesz danych wyjściowych iptables?
  • To pytanie powinno zostać przeniesione do Stackoverflow.

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ślenie shell=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 z LC_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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *