Windows ne trouve pas le fichier sur subprocess.call ()

103

Je reçois l'erreur suivante:

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

Mon code est:

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

Windows 7, 64 bits. Python 3.x dernier, stable.

Des idées?

Merci,

Sri
la source
et quel est ce fichier exécutable?
SilentGhost du
La partie exécutable "android" du SDK Android
Sri
2
Et est est disponible sur PATH
Sri
pouvez-vous l'exécuter à partir de la ligne de commande?
SilentGhost du
Un petit aperçu de ce que j'essaie d'accomplir. Ceci est pour Opendevice - un projet open source pour convertir des applications HTML5 en applications spécifiques à un appareil. J'essaye de remplacer os.system () dans bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… par subprocess.call ()
Sri

Réponses:

178

Lorsque la commande est un shell intégré, ajoutez un 'shell = True' à l'appel.

Par exemple pour dirvous tapez:

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

Pour citer la documentation:

Le seul moment où vous devez spécifier shell = True sous Windows est lorsque la commande que vous souhaitez exécuter est intégrée au shell (par exemple dir ou copy). Vous n'avez pas besoin de shell = True pour exécuter un fichier de commandes ou un exécutable basé sur la console.

Douglas Macdonald
la source
14
C'est parce qu'il n'y a pas d'exécutable appelé dir.exealors qu'il y a un /bin/lsin * nix. direst implémenté par CMD.EXE tout comme cdest implémenté par bash .
Apalala
1
Ceci est fortement déconseillé. docs.python.org/2/library/…
nu everest
11
@nueverest Uniquement lorsque la chaîne de commande est construite à partir d'une entrée externe
Jirka
L'alternative (plus sécurisée pour les entrées externes) est d'obtenir le PATHdepuis le os.environet de le rechercher manuellement.
asmeurer
Voir stackoverflow.com/a/32799942/3912576 pour une solution bien plus appropriée à ce problème.
SimonBiggs
33

Sous Windows, je crois que le subprocessmodule ne regarde pas dans le PATHsauf si vous passezshell=True car il est utilisé CreateProcess()dans les coulisses. Cependant, cela shell=Truepeut représenter un risque pour la sécurité si vous transmettez des arguments qui peuvent provenir de l'extérieur de votre programme. Pour subprocesspouvoir néanmoins trouver le bon exécutable, vous pouvez utiliser shutil.which. Supposons que l'exécutable dans votre PATHsoit nommé frob:

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

(Cela fonctionne sur Python 3.3 et supérieur.)

ptomate
la source
4
Une option python 2?
Naramsim
1
Vous avez raison et vous suggérez la bonne façon de résoudre ce problème. Cette réponse doit être acceptée. La réponse actuellement acceptée n'explique pas la cause et suggère une solution qui peut être dangereuse dans certains cas.
David Ferenczy Rogožan
18

Sous Windows, vous devez appeler via cmd.exe. Comme Apalala l'a mentionné, les commandes Windows sont implémentées dans cmd.exe et non en tant qu'exécutables séparés.

par exemple

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

/ c dit à cmd d'exécuter la commande suivante

C'est plus sûr que d'utiliser shell = True, qui permet les injections shell.

Sam Inverso
la source
Comment garder l'écran ouvert?
Moondra
2
@Moondra, si je vous comprends bien, essayez /kplutôt que /c. Entrez cmd /?sur la ligne de commande pour plus de détails.
User5910
@ User5910 Merci. Je vais essayer quand j'en aurai l'occasion.
Moondra
3

Si vous utilisez PowerShell, alors ce sera subprocess.call(['powershell','-command','dir']). Powershell prend en charge une grande partie des commandes POSIX

Couleuvre obscure
la source
2

Après avoir beaucoup gratté la tête, j'ai découvert que l'exécution d'un fichier situé dans C: \ Windows \ System32 \ tout en exécutant une version 32 bits de python sur une machine 64 bits est un problème potentiel, car Windows tente de surpasser le processus, et redirigez les appels vers C: \ Windows \ System32 vers C: \ Windows \ SysWOW64.

J'ai trouvé un exemple de résolution de ce problème ici: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

RBN
la source
1

Pour citer la documentation:

"Avant Python 3.5, ces trois fonctions comprenaient l'API de haut niveau à sous-traiter. Vous pouvez désormais utiliser run () dans de nombreux cas, mais beaucoup de code existant appelle ces fonctions."

SO: au lieu de subprocess.call, utilisez subprocess.run pour Python 3.5 et supérieur

Adrian Berca
la source
Vrai et utile.
Erick G. Hagstrom
0

J'ai rencontré le même problème pendant que j'appelais un PHP. La raison est que PHP n'est pas dans PATH, donc la commande PHP n'a pas été trouvée. Mais PowerShell a trouvé qu'il existe à l'emplacement actuel et il suggère de remplacer le 'PHP' par le '. \ PHP' si je fais confiance à cette commande. Ensuite, ça marche bien.

michael xie
la source