2011-01-29 6 views
30
import subprocess 
retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"]) 

Cuando ejecuto estas 2 líneas, estaré haciendo exactamente esto ?:¿Es esta la manera correcta de ejecutar un script de shell dentro de Python?

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

¿Por qué aparece este error? Pero cuando ejecuto go.sh normalmente, no obtengo 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 
+7

¿Su secuencia de comandos shell tienen la Hashbang correcta? – William

+1

¿Alguna vez resolvió esto? – Johnsyweb

Respuesta

1

Sí, eso es perfectamente bien si todo lo que estamos haciendo es llamar a la secuencia de comandos shell, a la espera de que se complete, y la recolección de su estado de salida, mientras que dejar su stdin, stdout y stderr ser heredado de su Python proceso. Si necesita más control sobre cualquiera de esos factores, entonces simplemente usa el subprocess.Popen más general, pero de lo contrario lo que tiene está bien.

+1

¿Puede decirme por qué me aparece este error? OSError: [Errno 8] Error de formato Exec. Cuando lo ejecuto normalmente todo va bien. – TIMEX

0

Sí, esta es la manera preferida para ejecutar algo ..

Dado que usted está pasando todos los argumentos a través de una matriz (que será utilizado gor un exec() - llamada de estilo internamente) y no como una cadena de argumentos evaluado por un shell también es muy seguro ya que la inyección de comandos de shell es imposible.

+0

¿Puede decirme por qué me aparece este error? OSError: [Errno 8] Error de formato Exec. Cuando lo ejecuto normalmente todo va bien. – TIMEX

+0

¿Es el script ejecutable para el usuario que ejecuta el script python? – ThiefMaster

33

OSError: [Errno 8] Exec format error

Este es un error reportado por el sistema operativo cuando se trata de ejecutar /home/myuser/go.sh.

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

Aquí es un script de ejemplo que se extiende desde la cáscara pero no desde Popen:

#\!/bin/sh 
echo "You've just called $0 [email protected]" 

Extracción de la \ de la primera línea corrige el problema.

+1

También me pasó un error similar, la primera línea fue un comentario bash y luego el shebang. Entonces Python no estaba enviando el script, pero cuando puse el shebang en la primera línea funcionó. ¿Puedes explicar por qué? – user1004985

+0

@ user1004985: La línea shebang *** debe *** ser la primera línea del archivo. Absolutamente. – Johnsyweb

11

Cambiar el código a continuación:

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

Aviso "shell = True"

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

On Unix, with shell=True: If args is a string, it specifies the command string to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt.

1

acabo de recibir este error en Mac OS, al intentar llamar un script de una línea usando subprocess.call. El script se ejecutó bien cuando se lo llamó desde la línea de comando. Después de agregar la línea de shebang #!/usr/bin/env sh, también se ejecutó bien a través de subprocess.call.

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

2

Recientemente me encontré con este problema con un script que se veía así:

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

El guión funcionó muy bien desde la línea de comandos, pero fallaron 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).

1
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 

llamada simplemente invocar Popen, utilice el método wait() esperará el popenargs completa

Cuestiones relacionadas