2012-03-29 15 views
27

Ich habe einige benutzerdefinierte Befehle.Popen Fehler: [Errno 2] Keine solche Datei oder Verzeichnis

# works 
subprocess.Popen(['python'], stdout=subprocess.PIPE) 

Aber wenn ich mein eigenes System Befehle wie deactivate haben, bekomme ich diesen Fehler

Traceback (most recent call last): 
    File "runner2.py", line 21, in <module> 
    main() 
    File "runner2.py", line 18, in main 
    subprocess.Popen(['deactivate',], stdout=subprocess.PIPE) 
    File "/usr/lib/python2.6/subprocess.py", line 633, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 

allein Lassen ich dies unter meinem Sandbox virtualenv ausführen müssen.

+2

Vielleicht 'Python' ist nicht auf der 'PATH' Umgebungsvariable, wenn Ihr Skript ausgeführt wird. Versuchen Sie, den vollständigen Pfad zu Python festzulegen, d. H. '/ Usr/bin/python'. –

+1

Können Sie erklären, was Sie erreichen möchten? Ich vermute, dass die Child-Shell, die Sie mit "subprocess" starten, das virtualenv-Aktivierungsskript nicht "bezogen" hat und nicht vom übergeordneten Python-Prozess geerbt wurde (vorausgesetzt, dass Sie es dort ausführen). –

Antwort

82

Versuchen Sie, einen zusätzlichen Parameter 'Shell = True' zum Popen Aufruf hinzuzufügen.

+40

Arbeitete für mich, aber warum? – YMomb

+0

funktioniert immer noch nicht – Woeitg

+5

@ YMomb: 'deaktivieren 'ist eine Shell-Funktion. Um es auszuführen, benötigen Sie eine Shell. Obwohl es sinnlos ist, es in einer neuen Shell auszuführen (die neue Shell wird es wahrscheinlich erst definieren, wenn 'venv/bin/activate' aufgerufen wird und das Kind normalerweise seine Elternumgebung sowieso nicht ändern kann, wenn OP hofft deaktiviere den aktuellen virtualenv set in der parent shell. Aus demselben Grund hebt 'subprocess.call ('cd')' "No this file or directory" auf und kann mit 'shell = True' behoben werden und es wäre genauso sinnlos. Siehe [Warum ist CD kein Programm?] (http://unix.stackexchange.com/q/38808/1321) – jfs

3

Sie müssen den vollständigen Pfad zu Ihrem Programm geben deactivate und dann sollte das Subprozessmodul in der Lage sein, es zu finden.

0

Ich Laichen Subprozesse wie folgt aus:

SHUTDOWN_CMD = os.path.sep.join(["c:", "windows", "system32", "shutdown.exe"]) 

def abortShutdown(): 
    os.spawnv(os.P_NOWAIT, SHUTDOWN_CMD, 
     [SHUTDOWN_CMD, '/A']) 
    time.sleep(3) 

Ich bin nicht da Python subprocess 2.5 nicht unterstützt wird. Ich musste den FULL-Pfad verwenden, um es funktioniert zu haben und ich denke, dass Sie auch den vollen Pfad zu Ihren benutzerdefinierten Befehlen verwenden müssen.

17

Nur eine Anmerkung. shell=True war wahrscheinlich die richtige Lösung für den O.p., da sie den folgenden Fehler nicht gemacht haben, aber Sie können auch den Fehler "Keine solche Datei oder Verzeichnis" erhalten, wenn Sie Ihre ausführbare Datei nicht von ihren Argumenten aufteilen.

import subprocess as sp, shlex 
sp.Popen(['echo 1']) # FAILS with "No such file or directory" 
sp.Popen(['echo', '1']) # SUCCEEDS 
sp.Popen(['echo 1'], shell=True) # SUCCEEDS, but extra overhead 
sp.Popen(shlex.split('echo 1')) # SUCCEEDS, equivalent to #2 

Ohne shell=True erwartet Popen die ausführbare Datei das erste Element des args zu sein, weshalb es nicht, gibt es keine „Echo 1“ ausführbar ist. Das Hinzufügen von shell=True ruft Ihre Systemshell auf und übergibt das erste Element von args an die Shell. d. h. für Linux ist Popen(['echo 1'], shell=True) äquivalent zu Popen('/bin/sh', '-c', 'echo 1'), was mehr Overhead ist, als Sie möglicherweise benötigen. Siehe Popen() documentation für Fälle, in denen shell=True tatsächlich nützlich ist.

+0

Diese Version des Fehlers kann auftreten, wenn Sie vergessen, Kommas zwischen den String-Literalen, wie Python zu setzen wird sie verketten: 'sp.Popen (['echo' '1']) # FAILS' –

Verwandte Themen