În prezent studiez test de penetrare și programarea Python. Vreau doar să știu cum aș merge la executarea unei comenzi Linux în Python. Comenzile pe care vreau să le execut sunt:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Dacă aș folosi doar print
în Python și rulați-l în terminal va face același lucru cu executarea acestuia ca și când l-ați fi tastat singur și apăsați Enter ?
Comentarii
Răspuns
Puteți utiliza os.system()
, astfel:
import os os.system("ls")
Sau în cazul dvs.:
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")
Mai bine, puteți utiliza apelul subprocesului, este mai sigur, mai puternic și probabil mai rapid:
from subprocess import call call("echo "I like potatos"", shell=True)
Sau, fără a invoca shell:
call(["echo", "I like potatos"])
Dacă doriți să capturați rezultatul, o modalitate de a face acest lucru este următoarea:
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))
Vă recomand să setați un timeout
în communicate
și, de asemenea, pentru a surprinde excepțiile pe care le puteți obține atunci când îl apelați. Acesta este un cod foarte predispus la erori, deci ar trebui să vă așteptați să apară erori și să le gestionați în consecință.
https://docs.python.org/3/library/subprocess.html
Comentarii
- os.system este depreciat de la versiunea 2.6. Subprocesul este modulul potrivit de utilizat.
- @binarysubstrate, depreciat ca neacceptat sau nedisponibil? ‘ am lucrat recent la mașină cu 2.7 (nu la alegere) și
os.system
funcționează în continuare. - De asemenea, dacă utilizați
subprocess.call
după cum este recomandat, poate fi necesar să specificațishell=True
… consultați aici - Cu Python 3.4 trebuie specificat shell = True, altfel comanda de apel nu va funcționa. În mod implicit, apelul va încerca să deschidă un fișier specificat de șir dacă nu este setat shell = True. De asemenea, se pare că în Python 3.5 apelul este înlocuit cu rularea
- Codul POSIX generic ar trebui probabil să apeleze
decode()
cu setul de caractere de laLC_CTYPE
variabilă de mediu.
Răspuns
Prima comandă scrie pur și simplu într-un fișier. Nu veți executa asta ca o comandă de shell deoarece python
poate citi și scrie în fișiere fără ajutorul unui shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Comanda iptables
este ceva ce poate doriți să executați extern. Cel mai bun mod de a face acest lucru este să utilizați modul de subproces .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Rețineți că această metodă nu folosește niciun shell, ceea ce este o cheltuială inutilă.
Răspuns
Cel mai rapid mod:
import os os.system("your command here")
Aceasta nu este cea mai flexibilă abordare ; dacă aveți nevoie de mai mult control asupra procesului dvs. decât „rulați-l o dată, până la finalizare și blocați până când acesta iese”, atunci ar trebui să utilizați în schimb modulul subprocess
.
Răspuns
Ca regulă generală, ar trebui să utilizați mai bine legările Python ori de câte ori este posibil (captare mai bună, printre alte avantaje.)
Pentru comanda echo
, este evident mai bine să folosiți python pentru a scrie în fișier, așa cum este sugerat în răspunsul lui @jordanm.
comanda iptables
, poate python-iptables
( pagina PyPi , Pagina GitHub cu descriere și doc ) vă va oferi ceea ce aveți nevoie (nu v-am verificat comanda specifică).
Acest lucru vă va face să depindeți de o lib extern, deci trebuie să cântăriți beneficiile. Folosind subprocesul funcționează, dar dacă doriți să utilizați ieșirea, va trebui să o analizați singur și să vă ocupați de modificările de ieșire în viitoarele versiuni iptables
.
Comentarii
- Un alt lucru de remarcat este că codul de testare a unității cu apeluri
subprocess
este mai puțin util. Da, puteți să apeluri, dar testele trebuie să facă presupuneri cu privire la rezultatele apelurilor externe. - Răspunsul dvs. seamănă mai mult cu sfatul. OP a întrebat în mod specific cum poate rula o comandă de sistem Linux din python.
- @kapad Da, dar a specificat și de ce voia să facă acest lucru și am propus o alternativă.
Răspuns
O versiune python a shell-ului dvs. Aveți grijă, nu am testat-o.
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
Comentarii
- Împărțirea șirurilor funcționează numai pentru cazurile simple. Pentru divizarea comenzilor în stil shell folosiți
shlex.split
Răspuns
Dacă doriți să executați această comandă în alt sistem după SSH, atunci ar trebui să utilizați modulul numit Paramiko. Este cu adevărat util.
Dacă executarea comenzii trebuie făcută de la mașina locală, atunci funcțiile modulului OS vor fi utile.
Pagina principală: https://www.paramiko.org/
Dezvoltare: https://github.com/paramiko/paramiko
bash
a fost o coajă umflată …os.system
recomandă utilizarea .