Windows non riesce a trovare il file su subprocess.call ()


103

Ricevo il seguente errore:

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

Il mio codice è:

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

Windows 7, 64 bit. Python 3.x più recente, stabile.

Qualche idea?

Grazie,


e cos'è questo file eseguibile?
SilentGhost,

La parte eseguibile "Android" dell'SDK Android
Sri

2
Ed è è accessibile PERCORSO
Sri

puoi eseguirlo dalla riga di comando?
SilentGhost,

Un piccolo retroscena di ciò che sto cercando di realizzare. Questo è per Opendevice, un progetto open source per convertire app HTML5 in app specifiche del dispositivo. Sto cercando di sostituire os.system () in bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… a subprocess.call ()
Sri

Risposte:


178

Quando il comando è un built-in della shell, aggiungi "shell = True" alla chiamata.

Ad esempio per dirte dovresti digitare:

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

Per citare dalla documentazione:

L'unica volta in cui è necessario specificare shell = True su Windows è quando il comando che si desidera eseguire è integrato nella shell (ad esempio dir o copy). Non è necessario shell = True per eseguire un file batch o un eseguibile basato su console.


14
Questo perché non c'è nessun eseguibile chiamato dir.exementre c'è un /bin/ls* nix. dirè implementato da CMD.EXE proprio come cdè implementato da bash .
Apalala

1
Questo è fortemente sconsigliato. docs.python.org/2/library/…
nu everest

11
@nueverest Solo quando la stringa di comando è costruita da un input esterno
Jirka

L'alternativa (più sicura per l'input esterno) è quella di ottenere PATHda os.environe cercarlo manualmente.
asmeurer

Vedi stackoverflow.com/a/32799942/3912576 per una soluzione molto più appropriata a questo problema.
SimonBiggs

33

Su Windows, credo che il subprocessmodulo non guardi a PATHmeno che tu non lo passishell=True perché viene utilizzato CreateProcess()dietro le quinte. Tuttavia, shell=Truepuò essere un rischio per la sicurezza se stai passando argomenti che potrebbero provenire dall'esterno del tuo programma. Per rendere subprocesscomunque in grado di trovare l'eseguibile corretto, puoi usare shutil.which. Supponiamo che l'eseguibile nel tuo PATHsia denominato frob:

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

(Funziona su Python 3.3 e versioni successive.)


4
Qualche opzione di Python 2?
Naramsim

1
Hai ragione e stai suggerendo il modo giusto per risolverlo. Questa risposta dovrebbe essere accettata. La risposta attualmente accettata non spiega la causa e suggerisce una soluzione che può essere pericolosa in alcuni casi.
David Ferenczy Rogožan

18

Su Windows devi chiamare tramite cmd.exe. Come accennato da Apalala, i comandi di Windows sono implementati in cmd.exe non come eseguibili separati.

per esempio

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

/ c dice a cmd di eseguire il comando follow

Questo è più sicuro rispetto all'utilizzo di shell = True, che consente iniezioni di shell.


Come manterrei lo schermo aperto?
Moondra

2
@ Moondra, se ti ho capito bene, prova /kinvece di /c. Immettere cmd /?nella riga di comando per i dettagli.
Utente5910

@ User5910 Grazie. Ci proverò quando ne avrò la possibilità.
Moondra

3

Se stai usando PowerShell, allora in esso sarà subprocess.call(['powershell','-command','dir']). Powershell supporta gran parte dei comandi POSIX


2

Dopo molti grattacapi, ho scoperto che l'esecuzione di un file che si trova in C: \ Windows \ System32 \ mentre si esegue una versione a 32 bit di python su una macchina a 64 bit è un potenziale problema, a causa del tentativo di Windows di superare il processo e reindirizza le chiamate a C: \ Windows \ System32 a C: \ Windows \ SysWOW64.

Ho trovato un esempio di come risolvere questo problema qui: http://code.activestate.com/recipes/578035-disable-file-system-redirector/


1

Per citare dalla documentazione:

"Prima di Python 3.5, queste tre funzioni comprendevano l'API di alto livello per il sottoprocesso. Ora puoi usare run () in molti casi, ma molto codice esistente chiama queste funzioni."

COSÌ: invece di subprocess.call usa subprocess.run per Python 3.5 e versioni successive


Vero e utile.
Erick G. Hagstrom

0

Ho riscontrato lo stesso problema mentre stavo chiamando un PHP. Il motivo è che PHP non è in PATH, quindi il comando PHP non è stato trovato. Ma PowerShell ha scoperto che esiste nella posizione corrente e suggerisce di sostituire "PHP" con ". \ PHP" se mi fido di questo comando. Quindi funziona bene.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.