1. Qu’est‑ce que le module subprocess de Python ?
Vue d’ensemble
Le module subprocess de Python est un outil puissant pour exécuter des commandes système et des programmes externes depuis Python. En utilisant ce module, vous pouvez gérer les entrées/sorties standard et les processus, ce qui facilite l’intégration de programmes externes avec des scripts Python. Il offre une méthode plus sûre et plus flexible pour contrôler les processus que les modules traditionnels os.system() ou commands.
Principaux cas d’utilisation
- Exécution de commandes shell : lancer des commandes système simples.
- Gestion de processus : exécuter des programmes externes et rediriger les entrées/sorties standard.
- Traitement asynchrone : gérer des tâches de longue durée et une exécution parallèle.
2. Utilisation de base : subprocess.run()
Utilisation de base
La fonction subprocess.run() vous permet d’exécuter des commandes système depuis Python de façon simple. Par exemple, pour lister les fichiers d’un répertoire, vous pouvez utiliser le code suivant :
import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
Ce code exécute la commande ls -l, capture sa sortie dans stdout et la traite dans Python. L’option capture_output=True capture la sortie standard, et text=True garantit que le résultat est manipulé comme une chaîne de caractères.
Gestion des erreurs
Lorsque vous utilisez subprocess.run(), vous pouvez récupérer les messages d’erreur via stderr si la commande échoue. Vous pouvez également vérifier le succès de l’exécution avec returncode.
result = subprocess.run(['ls', 'nonexistentfile'], capture_output=True, text=True)
if result.returncode != 0:
print(f"Error: {result.stderr}")
Dans cet exemple, si un fichier inexistant est indiqué, un message d’erreur sera affiché via la sortie d’erreur standard.

3. Exécution asynchrone : subprocess.Popen()
Traitement asynchrone avec Popen
Comme subprocess.run() est une opération synchrone, le programme Python ne peut pas passer à l’étape suivante tant que l’exécution de la commande n’est pas terminée. En revanche, avec subprocess.Popen(), vous pouvez lancer des processus de façon asynchrone et effectuer d’autres tâches simultanément.
import subprocess
proc = subprocess.Popen(['sleep', '5'], stdout=subprocess.PIPE)
print("Process started")
proc.wait()
print("Process completed")
Dans ce code, la commande sleep 5 s’exécute de façon asynchrone, permettant à d’autres tâches de continuer pendant son exécution.
Contrôle des entrées et sorties standard
Avec Popen, vous pouvez contrôler précisément la redirection des entrées et sorties standard. Par exemple, le code suivant lit des données depuis un fichier, les traite avec la commande cat, puis écrit le résultat dans un autre fichier.
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
proc = subprocess.Popen(['cat'], stdin=infile, stdout=outfile)
proc.wait()
Cela vous permet de rediriger les entrées et sorties standard des commandes externes vers des fichiers pour les traiter.
4. Cas d’utilisation : scripts d’automatisation
Sauvegarde de fichiers
Le module subprocess est très utile pour automatiser les tâches de gestion système et les opérations périodiques. Par exemple, le script suivant copie automatiquement des fichiers vers un répertoire de sauvegarde :
import subprocess
files_to_backup = ['file1.txt', 'file2.txt', 'file3.txt']
backup_dir = '/backup/directory/'
for file in files_to_backup:
subprocess.run(['cp', file, backup_dir])
Ce script copie les fichiers spécifiés dans un dossier de sauvegarde. Créer de simples scripts comme celui‑ci peut aider à automatiser les tâches de sauvegarde récurrentes.
Utilisation dans les pipelines CI/CD
Le module subprocess est également couramment utilisé dans les environnements d’Intégration Continue (CI) et de Déploiement Continu (CD). Il peut être intégré aux pipelines d’automatisation pour exécuter des scripts de test et gérer les processus de déploiement. Par exemple, il peut être utilisé pour lancer automatiquement des scripts de test et ne passer à l’étape suivante que si les tests réussissent.

5. Sécurité et bonnes pratiques
Risques de shell=True
The shell=True option est utilisée pour exécuter des commandes via le shell, mais elle comporte des risques de sécurité. En particulier, lorsqu’on transmet directement des entrées externes, il existe un danger d’attaques d’injection de shell. Utiliser shell=False réduit ce risque.
import subprocess
# Recommended usage (safe)
subprocess.run(['ls', '-l'])
# shell=True (use with caution)
subprocess.run('ls -l', shell=True)
Compatibilité multiplateforme
Les commandes système peuvent varier selon les différents systèmes d’exploitation. Vous pouvez utiliser le module platform de Python pour déterminer l’OS et adapter les commandes en conséquence.
import platform
import subprocess
if platform.system() == "Windows":
subprocess.run(['dir'], shell=True)
else:
subprocess.run(['ls', '-l'])
6. Dépannage et débogage
Erreurs courantes et solutions
Lors de l’utilisation de subprocess, des erreurs telles que « file not found » ou « permission denied » sont fréquentes. Elles peuvent être capturées avec stderr, et vous pouvez vérifier returncode pour obtenir des détails sur l’erreur.
Conseils de débogage
L’option check=True lève une exception si la commande échoue, ce qui vous aide à détecter les problèmes rapidement. Capturer la sortie standard et les messages d’erreur pour les journaux facilite également le débogage.
import subprocess
try:
result = subprocess.run(['ls', '-l'], check=True, capture_output=True, text=True)
print(result.stdout)
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}")
7. Traitement asynchrone avec asyncio
Traitement asynchrone avec asyncio
En utilisant asyncio, vous pouvez intégrer subprocess à un traitement asynchrone, permettant à plusieurs processus de s’exécuter en parallèle. L’exemple ci‑dessous exécute la commande ls de façon asynchrone et capture sa sortie.
import asyncio
import subprocess
async def run_command():
proc = await asyncio.create_subprocess_exec('ls', '-l',
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
stdout, stderr = await proc.communicate()
if stdout:
print(f'[stdout]n{stdout.decode()}')
if stderr:
print(f'[stderr]n{stderr.decode()}')
asyncio.run(run_command())
Ce code exécute la commande de façon asynchrone et traite la sortie standard ainsi que la sortie d’erreur. L’utilisation de asyncio permet une gestion efficace des tâches asynchrones.




![[Guide complet de l’instruction with de Python] Simplifier la gestion des ressources](https://www.python.digibeatrix.com/wp-content/uploads/2024/09/a899e1b4cda16b8a13042ca3ec2153b5-375x375.webp)
