Python subprocess : exécuter des commandes et des programmes externes
Python subprocess
est un module qui vous permet de commander, d’exécuter et d’évaluer des programmes externes à l’intérieur du code. Les deux fonctions principales de cet outil sont run()
et Popen()
.
Qu’est-ce que le module Python subprocess
?
Le module Python subprocess
fait partie de l’inventaire du langage de programmation depuis la version 2.4. Il s’agit d’un outil très complet et puissant que vous pouvez utiliser pour exécuter d’autres programmes ou commandes dans votre code. Il permet non seulement d’ouvrir des programmes, mais aussi de contrôler et d’ajuster le flux de données. Python subprocess
offre de nombreuses méthodes et fonctions, dont nous allons examiner les plus importantes dans cet article et les expliquer à l’aide d’exemples pratiques.
- Sécurité des données
- Outils de collaboration intégrés
- Hébergement dans des data centers européens
Python subprocess
: fonctionnement avec run()
Commençons par jeter un coup d’œil sur la structure et le fonctionnement de base du subprocess
de Python. Ce module est utilisé pour exécuter des sous-processus : Python fonctionne alors selon une hiérarchie parent-enfant, et prend le rôle de parent qui crée un processus enfant. La fonction la plus utilisée dans le module est run()
. Elle vous permet de lancer un processus via Python et ne commence les étapes suivantes que lorsque celui-ci a été entièrement exécuté.
Exemple de fonctionnement de subprocess
en Python avec run()
Nous allons maintenant utiliser cette fonction pour notre premier exemple du fonctionnement de Python subprocess
. Pour cela, on importe d’abord les modules subprocess
et sys
, puis nous exécutons une simple requête. Le code correspondant ressemble à ceci :
import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "print('bonjour')"])
pythonLa sortie est alors la suivante :
bonjour
pythonsubprocess.run
: il s’agit de la fonction proprement dite. Elle reçoit une liste de chaînes de caractères contenant la commande à exécuter.run()
exécute alors un nouveau programme Python.sys.executable
: c’est le chemin absolu qui mène au fichier Python avec lequel vous avez initialement appelé votre programme. Un tel chemin pourrait ressembler à/local/utilisateur/bin/exemple
.-c
:-c
est une option de ligne de commande avec laquelle la chaîne de caractères mentionnée est transmise pour exécution. Pour notre exemple, il s’agit d’un programme qui affiche le mot « bonjour ».
Exécuter Python subprocess
avec un script
Pour tester la façon dont vous utilisez le module pour un script que vous avez créé, vous pouvez essayer l’exemple suivant. Créez tout d’abord un script simple au format .py et enregistrez-le en tant que « exemplescript.py » :
print("Il fait beau aujourd’hui")
pythonPour exécuter ensuite ce fichier avec Python subprocess
, utilisez le code suivant :
import subprocess
result = subprocess.run(["python", "exemplescript.py"], capture_output=True, text=True)
print(result.stdout)
pythonLa sortie correspondante ressemblera alors à ceci :
Il fait beau aujourd’hui
pythonOuvrir des programmes externes
En principe, il est possible d’ouvrir n’importe quel programme avec Python subprocess
et la fonction run()
. La seule condition est de connaître le nom exact ou le chemin d’accès de ce programme sur votre système. Par exemple, dans le code suivant, nous ouvrons Notepad :
import subprocess
subprocess.run(["notepad"])
pythonCompletedProcess
et capture des sorties externes
Après ces exemples simples, nous allons désormais nous intéresser à la capture d’une sortie externe. Pour cela, vous exécutez un programme externe avec Python subprocess
comme ci-dessus, mais vous recevez en retour un objet appelé CompletedProcess
. Nous avons déjà brièvement intégré les adaptations nécessaires dans un exemple plus haut, nous allons maintenant les détailler. Notre point de départ est à nouveau notre premier code, mais avec quelques adaptations :
import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "print('bonjour')"], capture_output=True, text=True)
print("La sortie par défaut est :", result.stdout)
print("L’erreur par défaut est :", result.stderr)
pythonUne fois de plus, nous demandons au système d’afficher la chaîne de caractères « bonjour » au sein d’un processus enfant. Les deux arguments de mots-clés capture_output=True
et text=True
, que nous passons également à run()
, sont nouveaux. Si l’instruction est exécutée et qu’il n’y a pas d’erreur, vous obtenez un objet CompletedProcess
avec une liaison à result
. Cet objet contient des informations sur le code de sortie du programme que vous voulez exécuter et les transmet à result.stdout
et result.stderr
. stdout
indique la sortie par défaut et stderr
les éventuelles erreurs par défaut. Nous utilisons text=True
pour imprimer la sortie sous forme de chaîne de caractères. Comme aucune erreur standard n’est attendue, notre résultat est le suivant :
La sortie par défaut est : bonjour
L’erreur par défaut est :
pythonNous allons désormais modifier l’exemple précédent de manière à ce que stderr
ne soit pas vide. Voici le code correspondant :
import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "raise ValueError('erreur')"], capture_output=True, text=True)
print("La sortie par défaut est :", result.stdout)
print("L’erreur par défaut est :", result.stderr)
pythonAlors que la sortie standard reste vide, il y a maintenant une sortie pour stderr
:
La sortie par défaut est :
L’erreur par défaut est : Traceback (most recent call last):
File "<string>", line 1, in <module>
ValueError: erreur
pythonExécution à partir d’une fonction
Si vous voulez inclure une commande directement dans le code, Python subprocess
vous offre cette option. Dans ce cas, le code pourrait ressembler à cet exemple :
import subprocess
result = subprocess.run(["C:/Users/name/anaconda3/python", "-c", "print('Cette sortie a été prise directement depuis une fonction')"], capture_output=True, text=True, shell=True)
print("La sortie par défaut est :", result.stdout)
pythonLa sortie est alors la suivante :
La sortie par défaut est : Cette sortie a été prise directement depuis une fonction
pythonArrêter ou terminer des processus
Une autre utilisation très utile de Python subprocess
est obtenue par l’interaction de run()
avec l’argument timeout
. Il vous permet d’arrêter un programme externe si son exécution prend trop de temps. Pour cela, utilisez la fonction time.sleep
. Le code approprié est le suivant :
import subprocess
import sys
result = subprocess.run([sys.executable, "-c", "import time; time.sleep(3)"], timeout=1)
pythonLe processus enfant utilise time.sleep
pour s’arrêter pendant trois secondes. Cependant, comme vous avez demandé au système de déclencher un timeout après une seconde via timeout=1
, le résultat est une exception TimeoutExpired
.
Python subprocess
avec Popen()
Bien que run()
soit la fonction de subprocess
de Python la plus utilisée, il existe également d’autres classes Python importantes qui peuvent se révéler très utiles. Parmi elles, on trouve Popen()
. Cette classe est en quelque sorte le sous-ensemble de subprocess
et est un peu plus complexe à utiliser que run()
. En revanche, Popen()
vous donne plus de contrôle sur l’exécution et vous permet d’interagir avec l’entrée et la sortie. Cette classe doit son nom à une commande UNIX et signifie « pipe open » (littéralement « tuyau ouvert »).
Presque tous les arguments que vous pouvez utiliser avec run()
sont autorisés avec Popen()
. Cependant, contrairement à run()
, cette fonction n’attend pas la fin d’un processus : elle en lance un second en parallèle. Voici un exemple simple :
import subprocess
from time import sleep
def poll_and_read(process):
print(f"Voici la sortie après poll(): {process.poll()}")
print(f"Voici la sortie par défaut : {process.stdout.read().decode(‘utf-8’)}")
process = subprocess.Popen(["python", "timer.py", "3"], stdout=subprocess.PIPE)
poll_and_read(process)
sleep(2)
poll_and_read(process)
sleep(2)
poll_and_read(process)
process.wait()
print(f"Code de sortie du processus : {process.returncode}")
pythonIci, nous utilisons la méthode .poll()
pour vérifier si le processus est toujours en cours ou s’il est déjà terminé. Tant qu’il est encore en cours d’exécution, la valeur « none » est affichée. Ensuite, la méthode affiche le code de sortie. Avec .read()
, tous les octets qui se trouvaient jusqu’à présent dans .stdout
doivent être lus. Si vous exécutez le code, vous obtiendrez d’abord la valeur « none », puis la valeur contenue jusqu’à présent dans stdout
. Cela continuera jusqu’à ce que le processus soit terminé. poll()
reçoit alors la valeur « 0 ».
Déployer des applications et des sites Web directement avec GitHub : avec Deploy Now de IONOS, vous bénéficiez d’une configuration plus rapide, de workflows optimisés et d’une excellente évolutivité. Trouvez le tarif le plus adapté à vos besoins !