Executați comenzi shell în Python

Î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

  • os.system poate face acest lucru.
  • și m-am gândit bash a fost o coajă umflată …
  • Documentele pentru os.system recomandă utilizarea .
  • Aveți nevoie de ieșirea iptables?
  • Această întrebare ar trebui migrată în Stackoverflow.

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)) 

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ți shell=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 la LC_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

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *