Le module subprocess nous permet de démarrer un nouveau processus et de nous connecter à ses pipes d'entrée/sortie/erreur, ce qui permet d'obtenir la valeur de retour.
Utilisation du module subprocess
Le module subprocess recommande d'abord d'utiliser sa méthode run ; pour un usage plus avancé, vous pouvez utiliser directement l'interface Popen.
La syntaxe de la méthode run est la suivante :
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
- args : indique la commande à exécuter. Elle doit être une chaîne ou une liste de paramètres de type chaîne.
- stdin, stdout et stderr : l'entrée, la sortie et l'erreur standard du processus enfant. Leurs valeurs peuvent être subprocess.PIPE, subprocess.DEVNULL, un descripteur de fichier existant, un objet fichier déjà ouvert, ou None. subprocess.PIPE indique la création d'un nouveau pipe pour le processus enfant. subprocess.DEVNULL indique d'utiliser os.devnull. La valeur par défaut est None, ce qui signifie que rien n'est fait. De plus, stderr peut être fusionné dans stdout pour être affiché ensemble.
- timeout : Définit le délai d'expiration de la commande. Si le temps d'exécution de la commande dépasse le timeout, le processus enfant sera tué et une exception TimeoutExpired sera levée.
- check : Si ce paramètre est défini sur True et que le code de statut de sortie du processus n'est pas 0, une exception CalledProcessError sera levée.
- encoding : Si ce paramètre est spécifié, stdin, stdout et stderr peuvent recevoir des données de type chaîne et les encoder avec cet encodage. Sinon, seules les données de type bytes sont acceptées.
- shell : Si ce paramètre est True, la commande spécifiée sera exécutée via le shell du système d'exploitation.
L'appel de la méthode run renvoie une instance CompletedProcess. Il est similaire à l'utilisation directe de Popen ; l'implémentation est la même. En fait, il appelle aussi Popen, et est à peu près identique au constructeur Popen, par exemple :
Exemple
>>> subprocess.run(["ls", "-l", "/dev/null"])
crw-rw-rw- 1 root wheel 3, 2 5 4 13:34 /dev/null
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)
returncode: Le statut du processus enfant exécuté. Généralement, un statut de retour de 0 indique qu'il a terminé son exécution. Si la valeur est une valeur négative '-N', cela indique que le processus enfant a été terminé.
Exemple simple :
Exemple
def runcmd(command):
ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
if ret.returncode == 0:
print("succès :",ret)
else:
print("erreur :",ret)
runcmd(["dir","/b"])#Argument de type séquence
runcmd("exit 1")#Argument de type chaîne
Le résultat de sortie est le suivant :
success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py\n', stderr='') error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')
Méthode Popen()
Popen est le cœur de subprocess ; la création et la gestion des processus enfants sont prises en charge par lui.
Constructeur :
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
Paramètres courants :
- args : commande shell, qui peut être une chaîne ou un type séquence (par exemple, list, tuple)
- bufsize : taille du tampon. Utilisé lors de la création d'objets pipe pour les flux standard. La valeur par défaut est -1.
0 : aucune mise en tampon
1 : mise en tampon par ligne, disponible uniquement lorsque universal_newlines=True, c'est-à-dire en mode texte
Nombre positif : indique la taille du tampon
Nombre négatif : indique qu'il faut utiliser la taille de tampon par défaut du système. - stdin, stdout, stderr : représentent respectivement les descripteurs standard d'entrée, de sortie et d'erreur du programme
- preexec_fn : uniquement valide sur les plateformes Unix. Il est utilisé pour spécifier un objet appelable, qui sera appelé avant l'exécution du processus enfant.
- shell : Si ce paramètre est True, la commande spécifiée sera exécutée via le shell du système d'exploitation.
- cwd : utilisé pour définir le répertoire courant du processus enfant.
- env : utilisé pour spécifier les variables d'environnement du processus enfant. Si env=None, les variables d'environnement du processus enfant seront héritées du processus parent.
Créer un processus enfant, puis exécuter une commande simple :
Exemple
>>> p = subprocess.Popen('ls -l', shell=True)
>>> total 164
-rw-r--r-- 1 root root 133 Jul 4 16:25 admin-openrc.sh
-rw-r--r-- 1 root root 268 juil. 10 15:55 admin-openrc-v3.sh
...
>>> p.returncode
>>> p.wait()
0
>>> p.returncode
Vous pouvez aussi utiliserp = subprocess.Popen(['ls', '-cl'])pour créer un processus enfant.
Méthodes de l'objet Popen
- poll() : Vérifie si le processus s'est terminé. S'il est terminé, renvoie returncode ; sinon, renvoie None.
- wait(timeout) : Attend que le processus enfant se termine.
- communicate(input,timeout) : Interagit avec le processus enfant, en envoyant et lisant des données.
- send_signal(signal) : Envoie un signal au processus enfant.
- terminate() : Arrête le processus enfant, c'est-à-dire envoie le signal SIGTERM au processus enfant.
- kill() : Tue le processus enfant. Envoie le signal SIGKILL au processus enfant.
Exemple
import subprocess
def cmd(command):
subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
subp.wait(2)
if subp.poll() == 0:
print(subp.communicate()[1])
else:
print("Failed")
cmd("java -version")
cmd("exit 1")
Le résultat de sortie est le suivant :
java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode) 失败
Article de référence :
https://blog.csdn.net/weixin_42547344/article/details/80894760
https://blog.csdn.net/maosijunzi/article/details/80138458