Jeg studerer i øjeblikket penetrationstest og Python-programmering. Jeg vil bare vide, hvordan jeg vil gå til at udføre en Linux-kommando i Python. Kommandoerne, jeg vil udføre, er:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Hvis jeg bare bruger print
i Python og køre det i terminalen vil det gøre det samme som at udføre det, som om du selv skrev det og trykker på Enter ?
Kommentarer
Svar
Du kan bruge os.system()
på denne måde:
import os os.system("ls")
Eller i dit tilfælde:
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")
Endnu bedre, du kan bruge underprocessens opkald, det er sikrere, mere kraftfuld og sandsynligvis hurtigere:
from subprocess import call call("echo "I like potatos"", shell=True)
Eller uden at påkalde shell:
call(["echo", "I like potatos"])
Hvis du vil fange output, er en måde at gøre det på denne måde:
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))
Jeg anbefaler stærkt at indstille en timeout
i communicate
, og også for at opfange de undtagelser, du kan få, når du kalder det. Dette er en meget fejlbehæftet kode, så du kan forvente, at der sker fejl og håndtere dem i overensstemmelse hermed.
https://docs.python.org/3/library/subprocess.html
Kommentarer
- os.system er udfaset siden version 2.6. Underproces er det rigtige modul at bruge.
- @binarysubstrate, udfaset som ikke understøttet eller ikke tilgængeligt? Jeg ‘ har for nylig arbejdet på maskine med 2.7 (ikke efter eget valg), og
os.system
fungerer stadig. - Hvis du bruger
subprocess.call
som anbefalet, skal du muligvis angiveshell=True
… se her - Med Python 3.4 skal shell = True angives ellers fungerer opkaldskommandoen ikke. Som standard forsøger opkald at åbne en fil, der er angivet af strengen, medmindre shell = True er indstillet. Det ser også ud til, at kald i Python 3.5 erstattes med kørsel
- Generisk POSIX-kode skal sandsynligvis kalde
decode()
med tegnsæt fraLC_CTYPE
miljøvariabel.
Svar
Den første kommando skriver simpelthen til en fil. Du ville ikke udføre det som en shell-kommando, fordi python
kan læse og skrive til filer uden hjælp fra en shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
Kommandoen iptables
er noget, du måske vil udføre eksternt. Den bedste måde at gøre dette på er at bruge underprocessormodul .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Bemærk, at denne metode heller ikke bruger en shell, som er unødvendig overhead.
Svar
Den hurtigste måde:
import os os.system("your command here")
Dette er ikke den mest fleksible tilgang ; hvis du har brug for mere kontrol over din proces end “kør den en gang, til afslutning og blokerer indtil den afslutter”, skal du i stedet bruge subprocess
-modulet.
Svar
Som hovedregel ville du hellere bruge pythonbindinger, når det er muligt (bedre undtagelsesfangst blandt andre fordele.)
For kommandoen echo
er det naturligvis bedre at bruge python til at skrive i filen som foreslået i @jordanms svar.
Til iptables
kommando, måske python-iptables
( PyPi-side , GitHub-side med beskrivelse og dokument ) ville give det, du har brug for (jeg tjekkede ikke din specifikke kommando).
Dette får dig til at stole på en ekstern lib, så du skal veje fordelene. Brug af underprocesser fungerer, men hvis du vil bruge output, skal du selv analysere det og håndtere outputændringer i fremtidige iptables
versioner.
Kommentarer
- En anden ting at bemærke er, at enhedstestkode med
subprocess
opkald er mindre nyttigt. Ja, du kan spotte opkald, men testene skal antage antagelser om resultaterne på de eksterne opkald. - Dit svar er mere som råd. OP har specifikt spurgt, hvordan han kan køre en linux-systemkommando fra python.
- @kapad Ja, men han specificerede også hvorfor han ville gøre det, og jeg foreslog et alternativ.
Svar
En pythonversion af din shell. Vær forsigtig, jeg har ikke testet 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
- Opdeling af streng fungerer kun i de enkle tilfælde. Brug kommandopdeling til shell-stil
shlex.split
Svar
Hvis du vil udføre denne kommando i et andet system efter SSH, skal du muligvis bruge modulet ved navn Paramiko. Det er virkelig nyttigt.
Hvis udførelsen af kommandoen skal udføres fra en lokal maskine, er os modulfunktioner nyttige.
Hjemmeside: https://www.paramiko.org/
Udvikling: https://github.com/paramiko/paramiko
bash
var en oppustet skal …os.system
anbefaler at brugesubprocess
-modul.