Windows kann die Datei in subprocess.call () nicht finden

103

Ich erhalte die folgende Fehlermeldung:

WindowsError: [Error 2] The system cannot find the file specified

Mein Code lautet:

subprocess.call(["<<executable file found in PATH>>"])

Windows 7, 64 Bit. Python 3.x aktuell, stabil.

Irgendwelche Ideen?

Vielen Dank,

Sri
quelle
und was ist diese ausführbare Datei?
SilentGhost
Der ausführbare Teil "Android" des Android SDK
Sri
2
Und wird ist auf der PATH
Sri
Können Sie es über die Befehlszeile ausführen?
SilentGhost
Ein kleiner Hintergrund von dem, was ich erreichen will. Dies ist für Opendevice - ein Open Source-Projekt zum Konvertieren von HTML5-Apps in gerätespezifische Apps. Ich versuche os.system () in ersetzen bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/... subprocess.call ()
Sri

Antworten:

178

Wenn der Befehl eine integrierte Shell ist, fügen Sie dem Aufruf eine 'shell = True' hinzu.

ZB für dirSie würde schreiben:

import subprocess
subprocess.call('dir', shell=True)

Um aus der Dokumentation zu zitieren:

Sie müssen unter Windows nur shell = True angeben, wenn der Befehl, den Sie ausführen möchten, in die Shell integriert ist (z. B. Verzeichnis oder Kopie). Sie benötigen shell = True nicht, um eine Batchdatei oder eine konsolenbasierte ausführbare Datei auszuführen.

Douglas Macdonald
quelle
14
Das liegt daran, dass keine ausführbare Datei aufgerufen wird, dir.exewährend ein /bin/lsin * nix vorhanden ist. dirwird von CMD.EXE implementiert, ähnlich wie cdes von bash implementiert wird .
Apalala
1
Dies wird dringend empfohlen. docs.python.org/2/library/…
nu everest
11
@nueverest Nur wenn die Befehlszeichenfolge aus externen Eingaben aufgebaut ist
Jirka
Die Alternative (sicherer für externe Eingaben) besteht darin, die PATHvon der zu holen os.environund sie manuell zu durchsuchen.
Asmeurer
Eine weitaus geeignetere Lösung für dieses Problem finden Sie unter stackoverflow.com/a/32799942/3912576 .
SimonBiggs
32

Unter Windows glaube ich, dass das subprocessModul nur dann inPATHshell=True das Modul schaut, wenn Sie es bestehen, weil es CreateProcess()hinter den Kulissen verwendet wird. Dies shell=Truekann jedoch ein Sicherheitsrisiko darstellen, wenn Sie Argumente übergeben, die möglicherweise von außerhalb Ihres Programms stammen. Um subprocessdennoch die richtige ausführbare Datei zu finden, können Sie verwenden shutil.which. Angenommen, die ausführbare Datei in Ihrem PATHheißt frob:

subprocess.call([shutil.which('frob'), arg1, arg2])

(Dies funktioniert unter Python 3.3 und höher.)

Ptomato
quelle
4
Irgendeine Python 2 Option?
Naramsim
1
Sie haben Recht und schlagen den richtigen Weg vor, um das Problem zu beheben. Diese Antwort sollte akzeptiert werden. Die derzeit akzeptierte Antwort erklärt die Ursache nicht und schlägt eine Lösung vor, die in einigen Fällen gefährlich sein kann.
David Ferenczy Rogožan
18

Unter Windows müssen Sie über cmd.exe aufrufen. Wie von Apalala erwähnt, werden Windows-Befehle in cmd.exe nicht als separate ausführbare Dateien implementiert.

z.B

subprocess.call(['cmd', '/c', 'dir'])

/ c weist cmd an, den Befehl follow auszuführen

Dies ist sicherer als die Verwendung von shell = True, wodurch Shell-Injektionen möglich sind.

Sam Inverso
quelle
Wie würde ich den Bildschirm offen halten?
Moondra
2
@ Moondra, wenn ich dich richtig verstehe, versuche es /kstattdessen /c. Geben Sie cmd /?in der Befehlszeile Details ein.
User5910
@ User5910 Danke. Ich werde es versuchen, wenn ich eine Chance bekomme.
Moondra
3

Wenn Sie Powershell verwenden, wird es darin sein subprocess.call(['powershell','-command','dir']). Powershell unterstützt einen großen Teil der POSIX-Befehle

Dunkelschlange
quelle
2

Nach langem Kopfkratzen stellte ich fest, dass das Ausführen einer Datei in C: \ Windows \ System32 \ beim Ausführen einer 32-Bit-Version von Python auf einem 64-Bit-Computer ein potenzielles Problem darstellt, da Windows versucht, den Prozess zu übertreffen Leiten Sie Aufrufe an C: \ Windows \ System32 nach C: \ Windows \ SysWOW64 um.

Ich habe hier ein Beispiel gefunden, wie dies behoben werden kann: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

RBN
quelle
1

Um aus der Dokumentation zu zitieren:

"Vor Python 3.5 umfassten diese drei Funktionen die API für die Unterverarbeitung auf hoher Ebene. In vielen Fällen können Sie jetzt run () verwenden, aber viele vorhandene Codes rufen diese Funktionen auf."

SO: Verwenden Sie anstelle von subprocess.call subprocess.run für Python 3.5 und höher

Adrian Berca
quelle
Richtig und hilfreich.
Erick G. Hagstrom
0

Ich habe das gleiche Problem beim Aufrufen eines PHP festgestellt. Der Grund dafür ist, dass PHP nicht in PATH enthalten ist und der Befehl PHP nicht gefunden wurde. PowerShell hat jedoch festgestellt, dass es am aktuellen Speicherort vorhanden ist, und schlägt vor, das 'PHP' durch das '. \ PHP' zu ersetzen, wenn ich diesem Befehl vertraue. Dann läuft es gut.

Michael Xie
quelle