Opiskelen tällä hetkellä -tunkeutumistestausta ja Python-ohjelmointia. Haluan vain tietää, miten aion suorittaa Linux-komennon Pythonissa. Komennot, jotka haluan suorittaa, ovat:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Jos käytän vain print
Pythonissa ja ajaa se terminaalissa, toimiiko se samalla tavalla kuin suorittamalla kuin ikään kuin kirjoittaisit itse ja painaisit Enter ?
Kommentit
Vastaa
Voit käyttää os.system()
-tapaa seuraavasti:
import os os.system("ls")
Tai tapauksessasi:
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")
Vielä parempi: voit käyttää aliprosessin puhelua, se on turvallisempi, tehokkaampi ja todennäköisesti nopeampi:
from subprocess import call call("echo "I like potatos"", shell=True)
Tai ilman kuorta:
call(["echo", "I like potatos"])
Jos haluat kaapata lähdön, yksi tapa tehdä se on seuraava:
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))
Suosittelen timeout
ryhmässä communicate
, ja sieppaamaan myös poikkeukset, joita saat kutsuttaessasi sitä. Tämä on hyvin virhealtinen koodi, joten sinun pitäisi odottaa virheiden tapahtuvan ja käsitellä niitä vastaavasti.
https://docs.python.org/3/library/subprocess.html
Kommentit
- os.system on poistettu käytöstä versiosta 2.6 lähtien. Aliprosessi on oikea moduuli käytettäväksi.
- @binarysubstrate, vanhentunut kuten ei tuettu tai ei ole käytettävissä? Olen ’ työskennellyt äskettäin koneella, jossa on 2.7 (ei valinnaisesti), ja
os.system
toimii edelleen. - Lisäksi, jos käytät
subprocess.call
suosituksen mukaisesti, sinun on ehkä määritettäväshell=True
… katso täällä - Python 3.4: n kanssa shell = True on ilmoitettava, muuten kutsukomento ei toimi. Oletuksena kutsu yrittää avata merkkijonon määrittelemän tiedoston, ellei shell = True ole asetettu. Näyttää myös siltä, että Python 3.5: ssä puhelu korvataan ajolla
- Yleisen POSIX-koodin pitäisi todennäköisesti kutsua
decode()
merkilläLC_CTYPE
Ympäristömuuttuja.
Answer
Ensimmäinen komento kirjoittaa vain tiedostoon. Et suorita sitä komentokäskynä, koska python
voi lukea ja kirjoittaa tiedostoihin ilman komentotulkin apua:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
iptables
-komento kannattaa suorittaa ulkoisesti. Paras tapa tehdä tämä on käyttää aliprosessimoduuli .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Huomaa, että tämä menetelmä ei myöskään käytä kuorta, mikä on tarpeetonta yleiskustannusta.
Vastaa
Nopein tapa:
import os os.system("your command here")
Tämä ei ole joustavin tapa ; Jos tarvitset enemmän hallintaa prosessissasi kuin ”suorita se kerran loppuun asti ja estä, kunnes se poistuu”, käytä sen sijaan moduulia subprocess
.
vastaus
Pääsääntöisesti sinun tulisi käyttää paremmin python-sidoksia aina kun se on mahdollista (parempi poikkeusten sieppaus muiden etujen lisäksi.)
Komennolle echo
on tietysti parempi käyttää pythonia kirjoittaaksesi tiedostoon @jordanmin vastauksessa ehdotetulla tavalla.
iptables
-komento, ehkä python-iptables
( PyPi-sivu , GitHub-sivu, jossa on kuvaus ja asiakirja ) antaisi tarvitsemasi tiedot (en tarkistanut komentoasi).
Tämä tekisi sinut riippuvaiseksi ulkoinen lib, joten sinun on painotettava etuja. Aliprosessityö toimii, mutta jos haluat käyttää lähtöä, sinun on itse jäsenneltävä se ja käsiteltävä tulosten muutoksia tulevissa iptables
-versioissa.
Kommentit
- Toinen huomioitava asia on, että yksikön testauskoodi
subprocess
-puheluilla on vähemmän hyödyllinen. Kyllä, voit pilkata puhelut, mutta testien on tehtävä oletuksia ulkoisten puheluiden tuloksista. - Vastauksesi on enemmän kuin neuvoja. OP on kysynyt, kuinka hän voi suorittaa linux-järjestelmän komennon pythonista.
- @kapad Kyllä, mutta hän tarkensi myös miksi halusi tehdä niin, ja ehdotin vaihtoehtoa.
Vastaa
Python-versio shellistäsi. Ole varovainen, en ole testannut sitä.
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
Kommentit
- Merkkijonojen jakaminen toimii vain yksinkertaisissa tapauksissa. Käytä shell-tyylisen komennon jakamiseen
shlex.split
Vastaa
Jos haluat suorittaa tämän komennon jossakin muussa järjestelmässä SSH: n jälkeen, sinun on ehkä käytettävä Paramiko-nimistä moduulia. Se on todella hyödyllinen.
Jos komento on suoritettava paikallisesta koneesta, os-moduulin toiminnot ovat hyödyllisiä.
Kotisivu: https://www.paramiko.org/
Kehitys: https://github.com/paramiko/paramiko
bash
oli paisunut kuori …os.system
-dokumentit suosittelevatsubprocess
-moduuli.