Python: llamada de subproceso con shell = False no funciona

Estoy utilizando el script Python para invocar una máquina virtual Java. El siguiente comando funciona:

subprocess.call(["./rvm"], shell=False) # works subprocess.call(["./rvm xyz"], shell=True) # works 

Pero,

 subprocess.call(["./rvm xyz"], shell=False) # not working 

No funciona. Consejos de documentación de Python para evitar shell=True .

Necesitas dividir los comandos en cadenas separadas:

 subprocess.call(["./rvm", "xyz"], shell=False) 

Una cadena funcionará cuando shell=True pero necesita una lista de argumentos cuando shell=False

El módulo shlex es más útil para comandos más complicados y para manejar la entrada, pero es bueno aprender sobre:

 import shlex cmd = "python foo.py" subprocess.call(shlex.split(cmd), shell=False) 

shlex tut

Si desea usar shell=True , esto es legítimo, de lo contrario se habría eliminado de la biblioteca estándar. La documentación no dice para evitarlo, dice :

La ejecución de comandos de shell que incorporan entradas no saneadas de una fuente no confiable hace que un progtwig sea vulnerable a la inyección de shell, un grave defecto de seguridad que puede resultar en la ejecución de comandos arbitrarios. Por esta razón, el uso de shell=True se recomienda en los casos en que la cadena de comandos se construye a partir de una entrada externa .

Pero en su caso, no está construyendo el comando a partir de la entrada del usuario, su comando es constante, por lo que su código no presenta el problema de la inyección de shell . Usted tiene el control de lo que ejecutará el shell, y si su código no es malicioso per se, está seguro.

Ejemplo de inyección de shell

Para explicar por qué la inyección de shell es tan mala, este es el ejemplo utilizado en la documentación :

 >>> from subprocess import call >>> filename = input("What file would you like to display?\n") What file would you like to display? non_existent; rm -rf / # >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly... 

Editar

Con la información adicional que ha proporcionado al editar la pregunta, apéguese a la respuesta de Padraic . Debe usar shell=True solo cuando sea necesario.

Además de la respuesta de Enrico.bacis, hay dos formas de llamar a los progtwigs. Con shell=True , dale una cadena de comando completa. Con shell=False , dale una lista.

Si haces trucos de shell como *.jpg o 2> /dev/null , usa shell=True ; pero en general sugiero shell=False , es más duradero como dijo Enrico.

fuente

 import subprocess subprocess.check_call(['/bin/echo', 'beer'], shell=False) subprocess.check_call('/bin/echo beer', shell=True) 

salida

 beer beer 

En lugar de usar el directorio de nombre de archivo, agregue la palabra python delante de él, siempre que haya agregado la ruta de python a sus variables de entorno. Si no está seguro, siempre puede volver a ejecutar el instalador de Python, una vez más, siempre que tenga una nueva versión de python.

Esto es lo que quiero decir:

 import subprocess subprocess.Popen('python "C:/Path/To/File/Here.py"')