2012-03-29 13 views
27

Ho alcuni comandi personalizzati.Errore popen: [Errno 2] Nessun file o directory di questo tipo

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

Ma se ho i miei propri comandi di sistema come deactivate, ottengo quell'errore

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 

figuriamoci ho bisogno di eseguire questo sotto la mia sandbox virtualenv.

+2

Forse 'python' non si trova nella variabile di ambiente' PATH' quando viene eseguito lo script. Prova a impostare il percorso completo per python, ad esempio '/ usr/bin/python'. –

+1

Puoi spiegare cosa stai cercando di realizzare? Sospetto che la shell secondaria che stai lanciando con 'subprocess' non abbia" originato "lo script di attivazione virtualenv e non sia stata ereditata dal processo Python padre (supponendo che sia da dove la stai eseguendo). –

risposta

82

Provare a aggiungere un parametro aggiuntivo 'shell = True' alla chiamata Popen.

+40

Ha funzionato per me, ma perché? – YMomb

+0

non funziona ancora – Woeitg

+5

@YMomb: 'deactivate' è una funzione di shell. Per eseguirlo, hai bisogno di una shell. Anche se è inutile provare ad eseguirlo in una nuova shell (la nuova shell probabilmente non sarà definita fino a quando non viene chiamato 'venv/bin/activate' e il bambino normalmente non può modificare il suo ambiente genitore se OP spera di disattiva l'attuale set di virtualenv nella shell genitrice.Esso lo stesso motivo per cui 'subprocess.call ('cd')' solleva "Nessun file o directory" e può essere corretto usando 'shell = True' e sarebbe ugualmente pointless.See [Perché cd non è un programma?] (http://unix.stackexchange.com/q/38808/1321) – jfs

3

Devi fornire il percorso completo al tuo programma deactivate e quindi il modulo di sottoprocesso dovrebbe essere in grado di trovarlo.

sottoprocessi
0

sto deposizione delle uova del genere:

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) 

non sto usando il sottoprocesso dal Python 2.5 non lo supporta. Ho dovuto usare il percorso FULL per farlo funzionare e suppongo che devi anche usare il percorso completo per i tuoi comandi personalizzati.

17

Solo una nota. shell=True era probabilmente la soluzione corretta per l'o.p., poiché non hanno commesso l'errore seguente, ma puoi anche ottenere l'errore "Nessun file o directory" se non dividi il tuo eseguibile dai suoi argomenti.

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 

Senza shell=True, Popen aspetta l'eseguibile da primo elemento di args, che è il motivo per cui non c'è nessun "echo 1" eseguibile. L'aggiunta di shell=True richiama la shell di sistema e passa il primo elemento di args alla shell. Ad esempio, per linux, Popen(['echo 1'], shell=True) equivale a Popen('/bin/sh', '-c', 'echo 1'), che è più sovraccarico di quanto potrebbe essere necessario. Vedere Popen() documentation per i casi in cui shell=True è effettivamente utile.

+0

Questa versione dell'errore può verificarsi se si dimentica di inserire virgole tra le stringhe letterali, come Python li concatenerà: 'sp.Popen (['echo' '1']) # FAILS' –

Problemi correlati