Utför skalkommandon i Python

Jag studerar för närvarande penetrationstest och Python-programmering. Jag vill bara veta hur jag skulle gå till med att köra ett Linux-kommando i Python. Kommandona jag vill utföra är:

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

Om jag bara använder print i Python och kör det i terminalen kommer det att göra samma sak som att köra det som om du själv skrev det och tryck Enter ?

Kommentarer

  • os.system kan göra det.
  • och jag trodde bash var ett uppblåst skal …
  • Dokumenten för os.system rekommenderar att du använder subprocess -modul.
  • Behöver du utdata från iptables?
  • Denna fråga ska migreras till Stackoverflow.

Svar

Du kan använda os.system(), så här:

import os os.system("ls") 

Eller i ditt fall:

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

Ännu bättre, du kan använda underprocessens samtal, det är säkrare, kraftfullare och troligtvis snabbare:

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

Eller utan att anropa skal:

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

Om du vill fånga utdata är ett sätt att göra det så här:

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

Jag rekommenderar att du ställer in en timeout i communicate, och även för att fånga de undantag du kan få när du ringer till det. Detta är en mycket felbenägen kod, så du kan förvänta dig att fel inträffar och hantera dem i enlighet därmed.

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

Kommentarer

  • os.system har upphört sedan version 2.6. Delprocess är rätt modul att använda.
  • @binarysubstrate, utfas som inte stöds eller inte tillgängligt? Jag ’ har nyligen arbetat på maskin med 2,7 (inte av val) och os.system fungerar fortfarande.
  • Om du använder subprocess.call som rekommenderat kan du behöva ange shell=True … se här
  • Med Python 3.4 måste shell = True anges annars kommer kommandot call inte att fungera. Som standard försöker samtalet öppna en fil som anges av strängen såvida inte shell = True är inställt. Det ser också ut som att i Python 3.5-samtal ersätts med körning
  • Generisk POSIX-kod borde troligen ringa decode() med teckenuppsättning från LC_CTYPE miljövariabel.

Svar

Det första kommandot skriver helt enkelt till en fil. Du skulle inte köra det som ett skalkommando eftersom python kan läsa och skriva till filer utan hjälp av ett skal:

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

iptables -kommandot är något du kanske vill utföra externt. Det bästa sättet att göra detta är att använda underprocessmodul .

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

Observera att den här metoden inte heller använder ett skal, vilket är onödigt overhead.

Svar

Det snabbaste sättet:

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

Detta är inte det mest flexibla tillvägagångssättet ; om du behöver mer kontroll över din process än att ”köra den en gång, till slutförande och blockera tills den går ut”, ska du istället använda subprocess -modulen.

Svar

Som en allmän regel skulle du bättre använda pythonbindningar när det är möjligt (bättre undantagsfångning, bland andra fördelar.)

För echo -kommandot är det uppenbarligen bättre att använda python för att skriva i filen som föreslås i @jordanms svar.

För iptables -kommando, kanske python-iptables ( PyPi-sida , GitHub-sida med beskrivning och dokument ) skulle ge det du behöver (jag kollade inte ditt specifika kommando).

Detta skulle göra att du är beroende av en extern lib, så du måste väga fördelarna. Att använda delprocess fungerar, men om du vill använda utdata måste du analysera den själv och hantera utdataändringar i framtida iptables -versioner.

Kommentarer

  • En annan sak att notera är att enhetstestkod med subprocess samtal är mindre användbar. Ja, du kan spotta ut samtal, men testerna måste göra antaganden om resultaten på de externa samtalen.
  • Ditt svar är mer som råd. OP har specifikt frågat hur han kan köra ett linux-systemkommando från python.
  • @kapad Ja, men han specificerade också varför han ville göra det och jag föreslog ett alternativ.

Svar

En pythonversion av ditt skal. Var försiktig, jag har inte testat den.

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 

Kommentarer

  • Strängdelning fungerar bara för enkla fall. För kommandosplitning i skalstil använder du shlex.split

Svar

Om du vill utföra detta kommando i något annat system efter SSH kan du behöva använda modulen med namnet Paramiko. Det är väldigt användbart.

Om kommandokörningen måste göras från en lokal maskin kommer OS-modulfunktioner att vara till hjälp.

Hemsida: https://www.paramiko.org/

Utveckling: https://github.com/paramiko/paramiko

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *