Voer shell-commandos uit in Python

Ik “ben momenteel bezig met penetratietesten en programmeren in Python. Ik wil gewoon weten hoe ik een Linux-commando in Python zou uitvoeren. De commandos die ik wil uitvoeren zijn:

echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080 

Als ik gewoon print in Python en voer het uit in de terminal. Zal het hetzelfde doen als het uitvoeren alsof je het zelf typt en op Enter drukt?

Reacties

  • os.system kan dit.
  • en ik dacht bash was een opgeblazen shell …
  • De documenten voor os.system bevelen het gebruik van de module.
  • Heb je de uitvoer van iptables nodig?
  • Deze vraag moet worden gemigreerd naar Stackoverflow.

Antwoord

U kunt os.system() als volgt gebruiken:

import os os.system("ls") 

Of in jouw geval:

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

Beter nog, je kunt de aanroep van het subproces gebruiken, het is veiliger, krachtiger en waarschijnlijk sneller:

from subprocess import call call("echo "I like potatos"", shell=True) 

Of, zonder shell aan te roepen:

call(["echo", "I like potatos"]) 

Als u de uitvoer wilt vastleggen, is een manier om dit te doen als volgt:

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

Ik raad ten zeerste aan om een timeout in communicate, en ook om de uitzonderingen vast te leggen die je kunt krijgen als je het aanroept. Dit is een zeer foutgevoelige code, dus u kunt verwachten dat fouten optreden en ze dienovereenkomstig afhandelen.

https://docs.python.org/3/library/subprocess.html

Reacties

  • os.system is verouderd sinds versie 2.6. Subproces is de juiste module om te gebruiken.
  • @binarysubstrate, verouderd omdat het niet wordt ondersteund of niet beschikbaar is? Ik ‘ heb onlangs gewerkt aan een machine met 2.7 (niet naar keuze), en os.system werkt nog steeds.
  • Als u subprocess.call gebruikt zoals aanbevolen, moet u mogelijk shell=True specificeren … zie hier
  • Met Python 3.4 moet de shell = True worden opgegeven, anders werkt het call-commando niet. Standaard zal de aanroep proberen een bestand te openen dat gespecificeerd is door de string, tenzij de shell = True is ingesteld. Het lijkt er ook op dat in Python 3.5 de aanroep is vervangen door run
  • Generieke POSIX-code zou waarschijnlijk decode() moeten aanroepen met charset van LC_CTYPE omgevingsvariabele.

Answer

Het eerste commando schrijft gewoon naar een bestand. Je zou dat niet “uitvoeren als een shell-commando omdat python bestanden kan lezen en ernaar kan schrijven zonder de hulp van een shell:

with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1") 

Het iptables commando is iets dat je misschien extern wilt uitvoeren. De beste manier om dit te doen is door het subproces module .

import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"]) 

Merk op dat deze methode ook geen gebruik maakt van een shell, wat onnodige overhead is.

Antwoord

De snelste manier:

import os os.system("your command here") 

Dit is niet de meest flexibele benadering ; als je meer controle over je proces nodig hebt dan “één keer uitvoeren, tot voltooiing, en blokkeren totdat het afsluit”, dan zou je in plaats daarvan de subprocess module moeten gebruiken.

Answer

Als algemene regel kun je beter “python-bindingen gebruiken waar mogelijk (beter vangen van uitzonderingen, naast andere voordelen).

Voor het echo commando, is het duidelijk beter om Python te gebruiken om in het bestand te schrijven zoals voorgesteld in het antwoord van @jordanm.

Voor de iptables commando, misschien python-iptables ( PyPi-pagina , GitHub-pagina met beschrijving en document ) zou bieden wat je nodig hebt (ik heb je specifieke commando niet gecontroleerd).

Dit zou je afhankelijk maken van een externe lib, dus je moet de voordelen afwegen. Het gebruik van subprocessen werkt, maar als je de uitvoer wilt gebruiken, “zul je het zelf moeten ontleden, en moeten omgaan met uitvoerwijzigingen in toekomstige iptables versies.

Opmerkingen

  • Een ander ding om op te merken is dat unit testing code met subprocess oproepen minder nuttig is. Ja, je kunt de oproepen, maar de tests moeten aannames doen over de resultaten van de externe oproepen.
  • Je antwoord is meer als advies. Het OP heeft specifiek gevraagd hoe hij een Linux-systeemcommando kan uitvoeren vanuit python.
  • @kapad Ja, maar hij gaf ook aan waarom hij dit wilde doen en ik stelde een alternatief voor.

Antwoord

Een python-versie van je shell. Wees voorzichtig, ik heb hem niet getest.

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 

Reacties

  • String splitsen werkt alleen voor de eenvoudige gevallen. Gebruik voor het splitsen van commandos in shell-stijl shlex.split

Answer

Als je deze opdracht na SSH in een ander systeem wilt uitvoeren, moet je misschien de module Paramiko gebruiken. Het is erg handig.

Als de uitvoering van het commando vanaf een lokale machine moet worden uitgevoerd, zullen os-modulefuncties nuttig zijn.

Homepage: https://www.paramiko.org/

Ontwikkeling: https://github.com/paramiko/paramiko

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *