¿Es esta la forma correcta de ejecutar un script de shell en Python?

import subprocess retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"]) 

Cuando corra estas 2 líneas, ¿haré exactamente esto ?:

 /home/myuser/go.sh abc.txt xyz.txt 

¿Por qué me sale este error? Pero cuando ejecuto go.sh normalmente, no recibo ese error.

 File "/usr/lib/python2.6/subprocess.py", line 480, in call return Popen(*popenargs, **kwargs).wait() 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 8] Exec format error 

OSError: [Errno 8] Error de formato de ejecución

Este es un error informado por el sistema operativo al intentar ejecutar /home/myuser/go.sh .

Me parece que la línea shebang ( #! ) De go.sh no es válida.

Aquí hay un script de ejemplo que se ejecuta desde el shell pero no desde Popen :

 #\!/bin/sh echo "You've just called $0 $@." 

Eliminar el \ de la primera línea soluciona el problema.

Cambia el código a la siguiente:

 retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"], shell=True,) 

Observe “shell = True”

De: http://docs.python.org/library/subprocess.html#module-subprocess

En Unix, con shell = Verdadero: si args es una cadena, especifica la cadena de comandos que se ejecutará a través de la shell. Esto significa que la cadena debe tener el formato exactamente como se escribiría en el indicador de comandos del shell.

Recientemente me encontré con este problema con un script que se parecía a esto:

 % cat /tmp/test.sh <-- Note the empty line #!/bin/sh mkdir /tmp/example 

El script se ejecutó bien desde la línea de comando, pero falló con

 OSError: [Errno 8] Exec format error 

cuando se ejecuta a través de

 subprocess.Popen(['/tmp/test.sh']).communicate() 

(La solución, por supuesto, era eliminar la línea vacía).

Sí, eso está perfectamente bien si todo lo que estás haciendo es llamar al script de shell, esperar a que se complete y recostackr su estado de salida, mientras dejas que su stdin, stdout y stderr se hereden de tu proceso de Python. Si necesita más control sobre cualquiera de esos factores, entonces solo utiliza el subprocess.Popen más general.Abrir, pero por lo demás, lo que tiene está bien.

Acabo de recibir este error en Mac OS, al intentar llamar a un script de una línea utilizando subprocess.call . La secuencia de comandos se ejecutó bien cuando se llama desde la línea de comandos. Después de agregar la línea shebang #!/usr/bin/env sh , también funcionó bien a través de subprocess.call .

Aparece, mientras que el shell tiene un ejecutor predeterminado para los archivos de texto marcados como ejecutables, subprocess.Popen no lo hace.

 In :call?? Signature: call(*popenargs, **kwargs) Source: def call(*popenargs, **kwargs): """Run command with arguments. Wait for command to complete, then return the returncode attribute. The arguments are the same as for the Popen constructor. Example: retcode = call(["ls", "-l"]) """ return Popen(*popenargs, **kwargs).wait() File: /usr/lib64/python2.7/subprocess.py Type: function 

solo invoca a Popen, usa el método wait () espera que popenargs se complete

Sí, esta es la forma preferida de ejecutar algo.

Dado que está pasando todos los argumentos a través de una matriz (que se utilizará para una llamada de estilo exec () internamente) y no como una cadena de argumentos evaluada por un shell, también es muy seguro, ya que la inyección de comandos de shell es imposible.