ubuntuusers.de

[Python] Shell Befehle ausführen?

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

detructor15

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

Hy,

ist es irgendwie möglich, dass man in Python einen Shell Befehl ausführt?
Also bspw.:
sh /pfad/zu/einer/sh/datei.sh
?
Oder auch
sh /pfad/zu/einer/sh/datei.sh >/pfad/zu/einem/Ordner/logdatei.log
?

Und wenn ja, wie?

Gruß
detru

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

Natürlich.

Schau dir das Model 'subprocess' an.

€dit:
Was willst du überhaupt machen? In nahezu allen Fällen ist ein externer Prozess nicht nötig!

detructor15

(Themenstarter)

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

Was willst du überhaupt machen? In nahezu allen Fällen ist ein externer Prozess nicht nötig!

Da ich ET:QW starten will, ist dieser *Prozess* nötig 😀

Das ganze soll eine Art Frontend für ET:QW werden, sprich:
ET:QW installieren (evtl. sogar den ET:QW Linux Client automatisch downloaden)
ET:QW starten (hinter dem Button "starten" ist dann noch eine true/false box wo man sagen kann ob ein log kreiert werden soll )
autoexec.conf anlegen und dafür sorgen, dass sie beim start ausgeführt wird
autoexec.conf bearbeiten (gedit mit parameter öffnen)
logs anschauen (wieder mit gedit)
Befehlsliste (welche Befehle gibts, was tuen sie?)

Mich nervt es einfach total, dass es dafür kein FrontEnd vom Hersteller gibt und sowas mit dem eigentlichen Spiel nicht möglich ist.
Auch eine Befehlsliste konnte ich im Spiel bislang nirgendwo entdecken.

Das wird mein erstes Python Projekt...ich denke, dass ist angemessen. (bin gerad dabei mit Glade die ungefähre Oberfläche zu erstellen und will jetzt erstmal dem Start Button eine Funktion zuweisen um erstmal zu sehen wie das geht etc.)

Gruß
detru

*edit
*mein* Befehl wäre also bspw.

Popen ("/pfad/zur/Datei.sh", shell=true)


Oder

Popen ("/pfad/zur/Datei.sh >/log/Datei.log", shell=true)


?

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

Zumindest das Logs-Anschaun würde ich im Programm selbst machen und den Befehl zum editieren der autoexec.cfg mach bitte konfigurierbar.

Ich will mir das Spiel demnächst auch mal besorgen 😉

subprocess aus der Standardbibliothek ist jedenfalls genau was zu suchst!

detructor15

(Themenstarter)

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

Zumindest das Logs-Anschaun würde ich im Programm selbst machen und den Befehl zum editieren der autoexec.cfg mach bitte konfigurierbar.

ja das ist klar, im Notfall darf man auch im Code rumpfuschen 😉

aber sind meine beiden popen Befehle richtig?\^^

Flint

Avatar von Flint

Anmeldungsdatum:
25. Oktober 2006

Beiträge: 79

Ich rufe externe Prozesse meist als popen3-objekte auf ( http://docs.python.org/lib/popen3-objects.html )

import popen2
out,in,err=popen2.popen3("ls")

output=out.read()
errors=err.read()
#input=in.write()

So kann man den output auslesen, obendrein fehlermeldungen abfangen (sind ja keine exceptions mehr, wenn sie aus zweiter Hand kommen) und sogar beliebige Eingabeaufforderungen beantworten.

detructor15

(Themenstarter)

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

hey cool, danke Flint ☺
auch wenn das gerad voll an dem Vorbeiging was audax vermutlich beabsichtigte: nämlich das ich selbst meine grauen Zellen anstreng 😉

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

Und man soll subprocess benutzen. popen2 wird demnächst aus der Bibliothek entfernt.

from subprocess import Popen, PIPE
bufsize = 0
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)


http://docs.python.org/lib/node539.html

So macht man das mittlerweile 😉

Fredo Team-Icon

Avatar von Fredo

Anmeldungsdatum:
27. Juni 2005

Beiträge: 5244

Wohnort: Bochum

Guck Dir mal die Argumente "stdout" etc. von subprocess.Popen an. Damit hat man bequemen Zugriff auf STDOUT und kann dann die Ausgabe parsen.

Für so einfache Sachen ist sonst subprocess.call auch sehr nett. Damit hat man zwar keinen Zugriff auf STDOUT, aber man kann sehr einfach einen Befehl anschubsen und dessen returncode abfangen.

Liebe Grüße
Fredo

detructor15

(Themenstarter)

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

*schnief* ich fand das andere besser...is ja voll kompliziert 😲

from subprocess import Popen, PIPE
bufsize = 0
p = Popen(["/opt/etqw/etqw.sh"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)


so richtig?
Aber was machen diese stdin's und stdout's und warum nehmen die beide PIPE als Quelle? würde da nicht nur ein stdout reichen? an beide scheinen ja die gleichen Daten zu gehen *verwirrt ist*

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

Schau dir die Doku an, die hab ich verlinkt...

Da steht alles besser, als ich es erklären könnte.
Wirklich, wirklich, wirklich!

Fredo Team-Icon

Avatar von Fredo

Anmeldungsdatum:
27. Juni 2005

Beiträge: 5244

Wohnort: Bochum

detructor15 hat geschrieben:

*schnief* ich fand das andere besser...is ja voll kompliziert 😲

from subprocess import Popen, PIPE
bufsize = 0
p = Popen(["/opt/etqw/etqw.sh"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)


so richtig?
Aber was machen diese stdin's und stdout's und warum nehmen die beide PIPE als Quelle? würde da nicht nur ein stdout reichen? an beide scheinen ja die gleichen Daten zu gehen *verwirrt ist*

Du willst ja gar nichts an stdin senden, also kannst Du das IMO auch weglassen. Und warum man zum Schluss noch mal p.stdout und p.stdin in andere Variablen packt ist mir auch noch nicht ganz klar, ich bin bisher ohne ausgekommen. Da Du nur ein Argument hast, musst Du das nicht als Liste schreiben. bufsize=0 sollte übrigens die Standardeinstellung sein. Die Funktion von close_fds müsste ich auch noch mal erklärt bekommen, die könnte durchaus ihren Sinn haben, der sich mir aber noch nicht erschließt.

Also sollte das genügen (ungetestet):

from subprocess import Popen, PIPE
p = Popen("/opt/etqw/etqw.sh", stdout=PIPE)
# parse p.stdout
ret = p.wait()

detructor15

(Themenstarter)

Anmeldungsdatum:
16. Januar 2007

Beiträge: 5733

Schau dir die Doku an, die hab ich verlinkt...

Da steht alles besser, als ich es erklären könnte.
Wirklich, wirklich, wirklich!

werd ich nich wirklich schlau draus...da is nichts erklärt, nur ein paar Befehle hingedonnert und das wars...da ist selbst Java Benutzerfreundlicher...

@Fredo

Danke für die Aufklärung\^^
Frage an dich: ret = p.wait() bringt was?
ret = return...(denk ich mal) aber p.wait() ? was soll diese Funktion als Rückgabewert haben?
Zeit in $Zeiteinheit wie lange das Programm gelaufen ist?

Gruß
detru

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

popen2 closes all file descriptors by default, but you have to specify close_fds=True with subprocess.Popen.

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

detructor15 hat geschrieben:

Frage an dich: ret = p.wait() bringt was?

wait( )
Wait for child process to terminate. Returns returncode attribute.

Und jetzt frage ich mich ernsthaft: Warum denkst du eigentlich, dass ausgerechnet DU völlig ohne lesen der Doku auskommst? Was denkst, wofür wird Doku wohl geschrieben sein? Für Leute, die zu blöd auf einen Link zu klicken?
Ab jetzt darfst du dir die Doku-Schnipsel selbst suchen, wenn du nicht noch nen anderen Dummen findest, der dir alles vorkaut!

Antworten |