subprocess.call-Fragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
snakemake
User
Beiträge: 32
Registriert: Sonntag 6. Juni 2010, 19:20

Hallo,

ich arbeite mich in die Bibliothek "subprocess" ein. Nun, ich will einen Ping machen und so sieht mein Befehl aus:

Code: Alles auswählen

retval = subprocess.call("ping -c 2 localhost")
Das Problem ist, dass ich eine Exception bekomme:

Code: Alles auswählen

>>> retval = subprocess.call("ping -c 2 localhost", shell=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Wenn ich "shell=True" mache, geht es. Warum? Aber dabei wird die shell-Ausgabe angezeigt, die ich nicht haben will. Wie kriege ich die Ausgabe weg?

Lg.
Benutzeravatar
DrFaust
User
Beiträge: 21
Registriert: Freitag 15. Oktober 2010, 23:10

Das ist jetzt nur blind geraten: Könnte es sein, dass ohne shell=true die ganzen Umgebungsvariablen nicht zur Verfügung stehen? Hast du mal versucht, den Pfad des ping Befehls komplett anzugeben?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nein, man müßte nur mal in die Doku gucken und lesen:
Doku hat geschrieben: args should be a string, or a sequence of program arguments. The program to execute is normally the first item in the args sequence or the string if a string is given, but can be explicitly set by using the executable argument. When executable is given, the first item in the args sequence is still treated by most programs as the command name, which can then be different from the actual executable name. On Unix, it becomes the display name for the executing program in utilities such as ps.
Wenn Du Argumente hast, gib sie doch als Liste an!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
snakemake
User
Beiträge: 32
Registriert: Sonntag 6. Juni 2010, 19:20

Ich denke nicht, dass es an den Argumenten liegt. Wenn ich z.B. keine Argumente benutze, passiert das gleiche, siehe:

Code: Alles auswählen

>>> retval = subprocess.call("ifconfig wlan0", shell=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

snakemake hat geschrieben:Ich denke nicht, dass es an den Argumenten liegt. Wenn ich z.B. keine Argumente benutze, passiert das gleiche, siehe:

Code: Alles auswählen

>>> retval = subprocess.call("ifconfig wlan0", shell=False)

:roll: Wie würdest Du "wlan0" sonst bezeichnen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
snakemake
User
Beiträge: 32
Registriert: Sonntag 6. Juni 2010, 19:20

ups, sorry.

ich hab vorhin argumente gelesen, aber an optionen gedacht :p
das liegt daran, dass ich ein ähnliches problem in c hatte, wo ich die optionen mit einem array übergeben musste. das hab ich dann mit argumenten in python durcheinander gebracht. nochmals sorry :P:P:P

ich werds ma gleich testen. aber ich habe hier ein stück code liegen von einem framework, wo der author das so gemacht hat wie in meinem ersten post, also shell=True, allerdings kommen bei ihm keine ausgaben :/
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

DrFaust hat geschrieben:Das ist jetzt nur blind geraten: Könnte es sein, dass ohne shell=true die ganzen Umgebungsvariablen nicht zur Verfügung stehen?
Nein, die Umgebung wird vom aktuellen Prozess geerbt.[1] Es wird nur keine extra Shell gestartet die dann den Befehl ausfuehrt.

[1] Es sei denn man uebergibt eine neue per `env` an den Popen/call Aufruf.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Bei mir unter Windows XP klappt es so:

Code: Alles auswählen

In [20]: retval = subprocess.call(["ping", "-n", "2", "localhost"], shell=False)

Ping destiny [127.0.0.1] mit 32 Bytes Daten:

Antwort von 127.0.0.1: Bytes=32 Zeit<1ms TTL=128
Antwort von 127.0.0.1: Bytes=32 Zeit<1ms TTL=128

Ping-Statistik für 127.0.0.1:
    Pakete: Gesendet = 2, Empfangen = 2, Verloren = 0 (0% Verlust),
Ca. Zeitangaben in Millisek.:
    Minimum = 0ms, Maximum = 0ms, Mittelwert = 0ms
Nur weil ein Autor eines Stück Softwares etwas macht, muss das nicht immer der optimale weg sien ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
snakemake
User
Beiträge: 32
Registriert: Sonntag 6. Juni 2010, 19:20

Also bei mir unter Linux (Ubuntu) klappts nicht....also nicht so ganz, siehe:

Code: Alles auswählen

>>> retval = subprocess.call(["ping", "-c", "2", "localhost"], shell=True)
Usage: ping [-LRUbdfnqrvVaAD] [-c count] [-i interval] [-w deadline]
            [-p pattern] [-s packetsize] [-t ttl] [-I interface]
            [-M pmtudisc-hint] [-m mark] [-S sndbuf]
            [-T tstamp-options] [-Q tos] [hop1 ...] destination
>>> 
Wenn ich aber shell=False nehme, klappt es, allerdings halt mit Ausgabe, was ich ja nicht will :/
BlackJack

@snakemake: Wenn Du die Ausgabe nicht haben willst, dann musst Du sie halt umleiten.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mit ein paar Zeilen Code lässt sich das Erhalten der Ausgabe und auch das Ausführen von Fremdprogrammen etwas erleichtern:

Code: Alles auswählen

>>> from executie import Command
>>> Command('lsb_release -ds').output
'Ubuntu 9.10\n'
>>> Command('lsb_release -dgfhzgfhzus').output
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "executie.py", line 16, in __init__
    self.run()
  File "executie.py", line 22, in run
    raise ExitCodeError(proc.returncode)
executie.ExitCodeError: Execution failed with exit code 2
Antworten