Exécution d'un script bash depuis Python

111

J'ai un problème avec le code suivant:

callBash.py:

import subprocess
print "start"
subprocess.call("sleep.sh")
print "end"

sleep.sh:

sleep 10

Je veux que la «fin» soit imprimée après 10 s. (Je sais que c'est un exemple stupide, je pourrais simplement dormir dans python, mais ce simple fichier sleep.sh était juste comme un test)

user1638145
la source
Je l'ai aussi essayé avec "$! Bin / bash; sleep 10;"
user1638145
On ne sait pas sur quel problème ce questien essaie de poser, mais la question devrait probablement rester car il a accumulé un sac à main historique de plus ou moins bonnes suppositions comme réponses. Recherchez probablement également votre erreur spécifique et / ou lisez des questions connexes telles que stackoverflow.com/questions/4256107/…
tripleee

Réponses:

93

Rendre sleep.sh exécutable et ajouter shell=Trueà la liste des paramètres (comme suggéré dans les réponses précédentes) fonctionne bien. En fonction du chemin de recherche, vous devrez peut-être également ajouter ./un autre chemin approprié. (Ie, changez "sleep.sh"pour "./sleep.sh".)

Le shell=Trueparamètre n'est pas nécessaire (sous un système Posix comme Linux) si la première ligne du script bash est un chemin vers un shell; par exemple #!/bin/bash,.

James Waldby - jwpat7
la source
50

Si sleep.sha le shebang #!/bin/shet qu'il a les autorisations de fichier appropriées - exécutez chmod u+rx sleep.shpour vous assurer qu'il est dedans, $PATHalors votre code devrait fonctionner tel quel :

import subprocess

rc = subprocess.call("sleep.sh")

Si le script n'est pas dans le PATH, spécifiez le chemin complet vers lui, par exemple, s'il se trouve dans le répertoire de travail actuel:

from subprocess import call

rc = call("./sleep.sh")

Si le script n'a pas de shebang, vous devez spécifier shell=True:

rc = call("./sleep.sh", shell=True)

Si le script n'a pas d'autorisations exécutables et que vous ne pouvez pas le modifier, par exemple, en exécutant, os.chmod('sleep.sh', 0o755)vous pouvez lire le script sous forme de fichier texte et passer la chaîne au subprocessmodule à la place:

with open('sleep.sh', 'rb') as file:
    script = file.read()
rc = call(script, shell=True)
jfs
la source
34

En fait, il vous suffit d'ajouter l' shell=Trueargument:

subprocess.call("sleep.sh", shell=True)

Mais méfiez-vous -

Avertissement L'appel du shell système avec shell = True peut être un risque pour la sécurité s'il est combiné avec une entrée non approuvée. Consultez l'avertissement sous Arguments fréquemment utilisés pour plus de détails.

la source

zenpoy
la source
1
Cela ne fonctionnera pas si ce sleep.shn'est pas dans le PATH. Et s'il est sur le chemin et qu'il a le bon shebang, vous n'en avez pas besoin shell=True. Voir ma réponse
jfs
18

Si quelqu'un cherche à appeler un script avec des arguments

import subprocess

val = subprocess.check_call("./script.sh '%s'" % arg, shell=True)

N'oubliez pas de convertir les arguments en chaîne avant de passer, en utilisant str (arg).

Cela peut être utilisé pour passer autant d'arguments que vous le souhaitez:

subprocess.check_call("./script.ksh %s %s %s" % (arg1, str(arg2), arg3), shell=True)
Ponmudi VN
la source
10

Assurez-vous qu'il sleep.shdispose des autorisations d'exécution et exécutez-le avec shell=True:

#!/usr/bin/python

import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"
Adam Matan
la source
donc c'était le shell = True j'ai manqué. Pouvez-vous expliquer pourquoi il n'est pas suffisant de définir #! Bin / bash dans la première ligne du scricpt sh?
user1638145
3
L'erreur dans #!bin/bashest un manquant /. #!/bin/bashfonctionne comme je le note dans une réponse.
James Waldby - jwpat7
10

Si chmod ne fonctionne pas, vous essayez également

import os
os.system('sh script.sh')
#you can also use bash instead of sh

tester par moi merci

Harry1992
la source
La os.systemdocumentation recommande spécifiquement de l'éviter en faveur de subprocess(ces jours-ci, subprocess.run()). Si vous ne pouvez pas vous rendre subprocessau travail, il y a de fortes chances que vous ayez aussi des problèmes os.system().
tripleee le
3

Ajout d'une réponse car j'ai été dirigé ici après avoir demandé comment exécuter un script bash à partir de python. Vous recevez une erreur OSError: [Errno 2] file not foundsi votre script prend des paramètres. Disons par exemple que votre script a pris un paramètre de temps de veille: subprocess.call("sleep.sh 10")ne fonctionnera pas, vous devez le passer sous forme de tableau:subprocess.call(["sleep.sh", 10])

Matthew Lang
la source
Vous devez comprendre la signification réelle deshell=True mais oui, généralement l'éviter est votre meilleur jeu.
tripleee le