Seite 1 von 1

Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 15:46
von Raspx10
Hallo miteinander,
ich arbeite mich gerade in das Modul subprocess ein, da man os.system ja am besten nicht mehr verwenden sollte. Nun bin ich (wieder) auf ein Problem gestoßen, die Forum und Internet-Suche hat mir keine direkte Lösung gebracht.
Und zwar habe ich folgende Funktion definiert:

Code: Alles auswählen

import subprocess
def getMyIP():
      x = subprocess.Popen("Linux Befehl", shell=True, stdout=subprocess.PIPE)
      stdoutdata,stderrdata = x.communicate()
      return stdoutdata
Diese Funktion speichert mir meine Konsolenausgabe in stdoutdata (in dem Fall meine IP-Adresse) und gibt diese zurück.
Gebe ich stdoutdata in der gleichen Python Datei aus, so wird das richtige angezeigt (IP-Adresse). Binde ich nun die Python Datei in eine andere Python Datei und importiere die Funktion, so gibt sie folgendes aus:
<function getMyIP at 0x76a7c430>
Ausgabe erfolgt ganz normal:

Code: Alles auswählen

import lib_mit_getMyIP
IP = lib_mit_getMyIP.getMyIP()
print IP
Hab mir die letzten Tage den Kopf darüber zerbrochen. Ich habe nun alle Varianten von subprocess ausprobiert, bisher kein Erfolg. Hoffe ihr könnt mir helfen.
Vielen Dank schonmal
Raspx10

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 18:18
von Dav1d
Das hat nichts mit subprocess zu tun (obwohl du `shell=True` vermeiden solltest, oft ist es nicht nötig extra eine Shell zu starten). Kann es sein, dass du die "Klammern" bei dem Aufruf deiner Funktion vergessen hast oder die Datei, welche die Funktion enthält, zufällig getMyIP heißt?

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 18:21
von BlackJack
@Raspx10: Ich rate einfach mal das das nicht der tatsächliche Code ist. Bitte zeige was Du *wirklich* ausführst, sonst müssen wir hier wild herum raten wie denn nun der Code zu Deinem Problem aussehen mag. Das sollte eigentlich anders laufen. ;-)

Das ``shell=True`` muss aus dem Aufruf da übrigens noch rausnehmen, denn sonst hast Du Dir die Gründe warum man `os.system()` nicht verwenden sollte, auch bei `subprocess` wieder eingefangen.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 19:17
von Raspx10
Hallo,
danke für die schnelle Antwort! Das Problem lag wirklich an den Klammern, die hatte ich hier im Forum, aber nicht im Code :oops: Das werde ich jetzt nie wieder vergessen :wink:
Ok, das mit der Shell war eine Notlösung, weilbei langen Ausdrücken fällt mir sowas echt schwer es korrekt einzutippen. Oder mit Zeichen wie z.B. "\cp".
So sieht nämlich mein Code aus:

Code: Alles auswählen

import subprocess
def getMyIP():
      x = subprocess.Popen("/sbin/ifconfig eth0 | sed -n '/addr:/s/ [^r]*..//gp'", shell=True, stdout=subprocess.PIPE)
      stdoutdata, stderrdata = x.communicate()
      return stdoutdata
Hierbei stellt sich auch die Frage: Was macht man, wenn man das '/addr:/s/ [^r]*..//gp' korrekt übergeben möchte? Also doppelt ' geht ja bestimmt nicht? Da finde ich es wirklich einfacher alles in " zu setzen :? So wirklich gute Quellen habe ich dazu bisher auch noch nicht gefunden :/

Wünsche euch noch einen schönen Abend!
Raspx10

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 19:23
von BlackJack
@Raspx10: Man kann \ zum escapen benutzen aber letztendlich würde ich da keine Pipe in der Shell starten um ``sed`` zu starten für etwas was man auch in Python lösen kann.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 19:43
von Raspx10
Was bedeutet genau "\ zum escapen benutzen"?
Ich habe es auch anfangs damit versucht:

Code: Alles auswählen

import socket
sys_name=socket.gethostname()
ip_addr=socket.gethostname(sys_name)
print ip_addr
Aber das läuft nur unter Windows, unter Raspbian (Linux) liefert er mir nur 127.0.0.1
Oder kennst du noch eine andere Möglichkeit?

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Freitag 10. Juli 2015, 20:29
von BlackJack
@Raspx10: Das escapen von Anführungszeichen ist gleich das erste was im Tutorial im Abschnitt Strings erklärt wird.

Ansonsten findet man im Netz auch Code um die IP-Adresse zu einem Interface per `ioctl()`-Aufruf abzufragen:

Code: Alles auswählen

import fcntl
import socket
import struct


def get_ip_address(interface_name):
    return socket.inet_ntoa(
        fcntl.ioctl(
            socket.socket(socket.AF_INET, socket.SOCK_DGRAM).fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', interface_name[:15])
        )[20:24]
    )

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Samstag 11. Juli 2015, 07:52
von Raspx10
Hallo BlackJack,
danke für deine Antwort. Diesen Code habe ich im Netz auch schon gefunden und erfolgreich ausprobiert. Nur fand ich ihn nicht sehr verständlich im Vergleich zu meinem ersten Code mit "sed" :?

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Samstag 11. Juli 2015, 10:02
von Dav1d
Alternativ lässt du `sed` einfach weg und implementierst den Teil einfach in Python.

Einfach `/sbin/ifconfig eth0 ` aufrufen und aus der Ausgabe mit Python die IP rausziehen.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Samstag 11. Juli 2015, 11:46
von BlackJack
@Raspx10: Ob nun verständlicher oder nicht, das ist der direkte Weg so wie das ``ifconfig`` sehr wahrscheinlich intern auch macht. Würde ich dem starten von *drei* externen Programmen (Shell, ``ifconfig``, und ``sed``) vorziehen wo eines dann unter anderem auch genau das macht, die Information dann mit vielen anderen in Text ausgibt, aus dem man sie dann mühsam wieder rausparsen muss.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Samstag 11. Juli 2015, 16:08
von Raspx10
Ok, ich habe nun die ganze Zeit herumprobiert, den Befehl ohne die Shell einzubinden. Sehe das jetzt mal als Übung, danach werde ich dann wie vorgeschlagen schrittweise auf Python ausweichen. Und zwar habe ich den ifconfig und den sed Teil erst einmal getrennt, weil die zwei Befehle ja miteinander verkettet waren.

Code: Alles auswählen

import subprocess
# Ersteinmal die ganzen Infos von eth0 abspeichern
x = subprocess.Popen([r"/sbin/ifconfig", 'eth0'],stdout=subprocess.PIPE)
#Dann den sed Befehl anwenden
y = subprocess.Popen(['sed', '-n', r"\'/addr:/s [^r]*..//gp\'"], stdin=x.stdout, stdout=subprocess.PIPE)
Habe hier auch das escapen der ' mit \ angewendet und außerdem das rawinput für / benutzt. Er spuckt mir aber den Fehler " sed -e expression #1, char 25: unterminated address regex" aus :?
Mir ist auch noch nicht ganz klar was " [^r]*.." in dem sed-Befehl bedeutet? Also der sed Befehl ersetzt in der Zeile mit "addr" alle " [^r]*.." durch nichts (//), das glaube ich bisher herausgefunden zu haben :)

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Sonntag 12. Juli 2015, 12:46
von Sirius3
@Raspx10: Du fragst jetzt ernsthaft, was sed macht?
Raspx10 hat geschrieben:[...] Nur fand ich ihn nicht sehr verständlich im Vergleich zu meinem ersten Code mit "sed"
Die Anführungszeichen sind nötig, damit die Shell das Argument als ein Argument erkennt. Ohne zwischengeschaltete Shell sind sie aber überflüssig. Ansonsten ist der Ausdruck auch ein anderer als in Deinem ersten Beispiel.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Sonntag 12. Juli 2015, 20:44
von Raspx10
@Sirius3: Ich habe das Gefühl, du hast meine Fragestellung nicht richtig verstanden? Ich finde den sed-Befehl verständlichER.

Ich habe gelesen, dass man für Verzeichnisse die Anführungszeichen verwendet, damit nichts falsch gedeutet wird mit den Slash Zeichen.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Montag 13. Juli 2015, 06:27
von Sirius3
Was die Leute immer so lesen ...

@Raspx10: solange die Commandozeile von einer Shell interpretiert wird, mag das stimmen, hier nicht.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Montag 13. Juli 2015, 14:07
von Raspx10
Ok, danke für deine Antwort. Es hat funktioniert, nun würde ich versuchen, alles in Python zu lösen. Aber dazu muss ich immer noch wissen, was der Ausdruck "[^r]*.." genau beschreibt. Weißt du da auch etwas darüber?

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Montag 13. Juli 2015, 14:21
von BlackJack
@Raspx10: Da weiss die Dokumentation von ``sed`` mehr drüber: sed, a stream editor.

Grundsätzlich könntest Du aber auch selber überlegen wie man das lösen könnte ohne eine ``sed``-Lösung 1:1 nach Python umzuschreiben.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Montag 13. Juli 2015, 16:51
von snafu
Raspx10 hat geschrieben:

Code: Alles auswählen

import lib_mit_getMyIP
IP = lib_mit_getMyIP.getMyIP()
print IP
Wieso eigentlich `print`? Sicher, dass du nicht lieber ``subprocess.call(['echo', IP])`` verwenden möchtest...? :twisted:

Mal im Ernst: Ein Aufruf von `sed` hat normalerweise nichts in einem Python-Programm zu suchen. Python kann nämlich all das, was `sed` auch kann, da es reichlich Funktionalität zur Verarbeitung von Text anbietet. Außerdem ist jedes externe Tool ja eine weitere Abhängigkeit. Und Abhängigkeiten (d.h. alles was nicht zu Pythons Boardmitteln gehört) sollte man IMHO nur mitschleppen, wenn das Schreiben des nötigen Codes ohne die Abhängigkeit zu umfangreich wäre. In deinem Fall ist die Verarbeitung der Rückgabe des `ifconfig`-Befehls aber lediglich ein Zweizeiler.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Montag 13. Juli 2015, 16:59
von snafu
BlackJack hat geschrieben:Grundsätzlich könntest Du aber auch selber überlegen wie man das lösen könnte ohne eine ``sed``-Lösung 1:1 nach Python umzuschreiben.
Dem stimme ich zu. Anstatt die `sed`-Syntax zu entschlüsseln, kann man sich auch einfach die Ausgabe von ``ifconfig eth0`` ansehen und überlegen, wie man an den gewünschten Textausschnitt kommt. Dazu bedarf es einer schrittweisen Vorgehensweise. Mit den einzelnen Schritten dürfte man als Anfänger auch etwas länger beschäftigt sein. Wenn man da systematisch rangeht, wird man auch spezifische Fragen haben. Die Fragen, die man durch Recherche nicht selbst beantwortet bekommt, kann man dann gerne hier im Forum stellen.

Re: Mit subprocess zugewiesene Variable exportieren

Verfasst: Dienstag 14. Juli 2015, 11:07
von sparrow
Eine von dir in Python implementierte Lösung hätte für dich außerdem den Vorteil, dass du sie bei Bedarf flexibler machen könntest. Hier gibt es zum Beispiel kein eth0.