Windows no puede encontrar el archivo en subprocess.call ()

103

Estoy teniendo el siguiente error:

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

Mi codigo es:

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

Windows 7, 64 bits. Python 3.x más reciente, estable.

¿Algunas ideas?

Gracias,

Sri
fuente
y que es este archivo ejecutable?
SilentGhost
La parte ejecutable "android" del SDK de Android
Sri
2
Y se está disponible en PATH
Sri
¿Puedes ejecutarlo desde la línea de comandos?
SilentGhost
Un poco de historia de lo que estoy tratando de lograr. Esto es para Opendevice, un proyecto de código abierto para convertir aplicaciones HTML5 en aplicaciones específicas para dispositivos. Estoy intentando reemplazar os.system () en bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… a subprocess.call ()
Sri

Respuestas:

178

Cuando el comando es un shell incorporado, agregue un 'shell = True' a la llamada.

Por ejemplo, para dirti escribirías:

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

Para citar de la documentación:

La única vez que necesita especificar shell = True en Windows es cuando el comando que desea ejecutar está integrado en el shell (por ejemplo, dir o copiar). No necesita shell = True para ejecutar un archivo por lotes o un ejecutable basado en consola.

Douglas Macdonald
fuente
14
Eso es porque no hay ningún ejecutable llamado dir.exemientras hay un /bin/lsin * nix. CMD.EXE lodir implementa de forma muy similar a como lo implementa bash . cd
Apalala
1
Esto está fuertemente desaconsejado. docs.python.org/2/library/…
nu everest
11
@nueverest Solo cuando la cadena de comando se construye a partir de una entrada externa
Jirka
La alternativa (más segura para la entrada externa) es obtener el PATHde os.environy buscarlo manualmente.
asmeurer
Consulte stackoverflow.com/a/32799942/3912576 para obtener una solución mucho más adecuada a este problema.
SimonBiggs
33

En Windows, creo que el subprocessmódulo no se ve en el a PATHmenos que paseshell=True porque se usa CreateProcess()detrás de escena. Sin embargo, shell=Truepuede ser un riesgo para la seguridad si pasa argumentos que pueden provenir de fuera de su programa. No subprocessobstante, para poder encontrar el ejecutable correcto, puede utilizar shutil.which. Suponga que el ejecutable en su PATHse llama frob:

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

(Esto funciona en Python 3.3 y superior).

tomate
fuente
4
¿Alguna opción de Python 2?
Naramsim
1
Tienes razón y estás sugiriendo la forma correcta de solucionarlo. Esta respuesta debe aceptarse. La respuesta actualmente aceptada no explica la causa y sugiere una solución que puede ser peligrosa en algunos casos.
David Ferenczy Rogožan
18

En Windows, debe llamar a través de cmd.exe. Como mencionó Apalala, los comandos de Windows se implementan en cmd.exe no como ejecutables separados.

p.ej

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

/ c le dice a cmd que ejecute el comando de seguimiento

Esto es más seguro que usar shell = True, que permite inyecciones de shell.

Sam Inverso
fuente
¿Cómo mantendría la pantalla abierta?
Moondra
2
@Moondra, si te entiendo correctamente, prueba en /klugar de /c. Ingrese cmd /?en la línea de comando para obtener más detalles.
User5910
@ User5910 Gracias. Lo intentaré cuando tenga la oportunidad.
Moondra
3

Si está usando powershell, entonces estará subprocess.call(['powershell','-command','dir']). Powershell admite una gran parte de los comandos POSIX

Darksnake
fuente
2

Después de mucho rascarme la cabeza, descubrí que ejecutar un archivo que se encuentra en C: \ Windows \ System32 \ mientras se ejecuta una versión de Python de 32 bits en una máquina de 64 bits es un problema potencial, debido a que Windows intenta superar en inteligencia al proceso, y redirigir las llamadas a C: \ Windows \ System32 a C: \ Windows \ SysWOW64.

Encontré un ejemplo de cómo solucionar esto aquí: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

RBN
fuente
1

Para citar de la documentación:

"Antes de Python 3.5, estas tres funciones comprendían la API de alto nivel para subprocesar. Ahora puede usar run () en muchos casos, pero muchos de los códigos existentes llaman a estas funciones".

SO: en lugar de subprocess.call use subprocess.run para Python 3.5 y superior

Adrian Berca
fuente
Verdadero y útil.
Erick G. Hagstrom
0

Encontré el mismo problema mientras llamaba a PHP. La razón es que PHP no está en PATH, por lo que no se encontró el comando PHP. Pero PowerShell descubrió que existe en la ubicación actual y sugiere reemplazar el 'PHP' por el '. \ PHP' si confío en este comando. Entonces funciona bien.

michael xie
fuente