Lancer une commande shell avec un script python, attendre la fin et retourner au script
-
11-07-2019 - |
Question
J'ai un script python qui doit lancer une commande shell pour chaque fichier d'un répertoire:
import os
files = os.listdir(".")
for f in files:
os.execlp("myscript", "myscript", f)
Cela fonctionne bien pour le premier fichier, mais après le script "myscript". Si la commande est terminée, l'exécution s'arrête et ne revient pas au script python.
Comment puis-je faire? Dois-je fork ()
avant appeler os.execlp ()
?
La solution
sous-processus: module
sous-processus
vous permet de générer de nouveaux processus, se connecter à leur entrée / sortie / erreur tuyaux et obtenir leurs codes de retour.
http://docs.python.org/library/subprocess.html
Utilisation:
import subprocess
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.wait()
print process.returncode
Autres conseils
Vous pouvez utiliser sous-processus.Popen
. Il y a plusieurs façons de le faire:
import subprocess
cmd = ['/run/myscript', '--arg', 'value']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in p.stdout:
print line
p.wait()
print p.returncode
Ou, si vous ne vous souciez pas de ce que le programme externe fait réellement:
cmd = ['/run/myscript', '--arg', 'value']
subprocess.Popen(cmd).wait()
Le module de sous-processus a fait son chemin depuis 2008. En particulier, check_call
et check_output
simplifient encore davantage les tâches de sous-processus simples. La famille de fonctions check _ *
permet de générer une exception en cas de problème.
import os
import subprocess
files = os.listdir('.')
for f in files:
subprocess.check_call( [ 'myscript', f ] )
Toute sortie générée par myscript
s'affichera comme si votre processus l'avait produite (techniquement myscript
et votre script python partage le même stdout). Il existe plusieurs moyens d'éviter cela.
-
check_call (['myscript', f], stdout = subprocess.PIPE)
La sortie standard sera supprimée (attention simyscript
produit plus que 4k de sortie). stderr sera toujours affiché sauf si vous ajoutez l'optionstderr = subprocess.PIPE
. -
check_output (['myscript', f])
check_output
renvoie la sortie standard sous forme de chaîne, de sorte qu'elle ne soit pas affichée. stderr est toujours affiché sauf si vous ajoutez l'optionstderr = sous-processus.STDOUT
.
Les fonctions os.exec * ()
remplacent le programme actuel par le nouveau. Lorsque ce programme se termine, votre processus prend fin. Vous voulez probablement os.system ()
.
utiliser spawn
import os
os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', '/dev/null')
J'utilise os.system
import os
os.system("pdftoppm -png {} {}".format(path2pdf, os.path.join(tmpdirname, "temp")))
cela a bien fonctionné pour moi!
shell_command = & l; ls -l "
subprocess.call (shell_command.split ())