web-dev-qa-db-fra.com

Est-ce la bonne façon d'exécuter un script Shell dans Python?

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

Est-ce que je vais faire exactement cela quand je lance ces 2 lignes ?:

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

Pourquoi ai-je cette erreur? Mais lorsque je lance go.sh normalement, je ne reçois pas cette erreur.

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
30
TIMEX

OSError: [Errno 8] Erreur de format Exec

Il s'agit d'une erreur signalée par le système d'exploitation lors de la tentative d'exécution de /home/myuser/go.sh.

Il me semble que la ligne Shebang (#!) de go.sh n'est pas valide. 

Voici un exemple de script exécuté à partir du shell mais pas à partir de Popen:

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

Supprimer le \ de la première ligne résout le problème.

33
Johnsyweb

Changez le code comme suit:

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

Remarquez "Shell = True"

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

Sous Unix, avec Shell = True: Si args est une chaîne , Il spécifie la chaîne de commande À exécuter via le shell. Cela signifie que la chaîne doit être [.____. .] mis en forme exactement comme si était tapé à l'invite du shell.

10
jbp

J'ai récemment rencontré ce problème avec un script qui ressemblait à ceci:

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

Le script a fonctionné correctement à partir de la ligne de commande, mais a échoué avec

OSError: [Errno 8] Exec format error

lorsqu'il est exécuté via

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

(La solution, bien sûr, était de supprimer la ligne vide).

3
unutbu
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

appelez simplement appeler Popen, utilisez la méthode wait () attendez que popenargs se termine

1
张小诚

Oui, c'est très bien si vous appelez le script Shell, attendez son achèvement et récupérez son statut de sortie, tout en laissant ses stdin, stdout et stderr hérités de votre processus Python. Si vous avez besoin de plus de contrôle sur l’un de ces facteurs, utilisez simplement le plus général subprocess.Popen , mais sinon, ce que vous avez est bon.

1
Adam Rosenfield

Je viens de recevoir cette erreur sur Mac OS, alors que j'essayais d'appeler un script d'une ligne à l'aide de subprocess.call. Le script a fonctionné correctement lorsqu'il a été appelé à partir de la ligne de commande. Après avoir ajouté la ligne #!/usr/bin/env sh de Shebang, il a également fonctionné correctement via subprocess.call.

Apparemment, alors que l'environnement de ligne de commande possède un exécuteur par défaut pour les fichiers texte marqués comme étant exécutable, ce n'est pas le cas avec subprocess.Popen.

1
George

Oui, c'est la manière préférée d'exécuter quelque chose ..

Puisque vous passez tous les arguments dans un tableau (qui sera utilisé pour un appel de style exec () en interne) et non comme une chaîne d’argument évaluée par un shell, elle est également très sécurisée, car l’injection de commandes de shell est impossible.

0
ThiefMaster