python_subprocess
                Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| python_subprocess [2024/11/01 19:54] – luc | python_subprocess [2024/11/02 12:46] (Version actuelle) – luc | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | ====== Python subprocess ====== | ||
| + | |||
| + | Il s'agit d' | ||
| + | Les cas d' | ||
| + | |||
| + | On va utiliser le module '' | ||
| + | |||
| + | ===== Exécuter 1 processus ===== | ||
| + | |||
| + | La fonction de haut niveau '' | ||
| + | |||
| + | <code python> | ||
| + | import subprocess | ||
| + | |||
| + | result = subprocess.run([" | ||
| + | print(" | ||
| + | </ | ||
| + | |||
| + | On notera : | ||
| + | * La commande est bloquante, elle attend la fin du processus pour continuer l' | ||
| + | * Les différents arguments de la fonction sont donnés dans une liste (grosso modo, chaque espace de la ligne de commande délimite un élément de la liste) | ||
| + | * On peut récupérer les entrées / sorties standard (stdin, stdout), mais également celle d' | ||
| + | * On récupère un objet ici appelé '' | ||
| + | |||
| + | === Les options === | ||
| + | |||
| + | <code python> | ||
| + | subprocess.run() | ||
| + | |||
| + | # capture_output : si True, capture stdout et stderr | ||
| + | # text = True : la sortie est un string plutôt qu'un byte | ||
| + | # cwd : définit le current work directory | ||
| + | # timeout : en secondes | ||
| + | |||
| + | </ | ||
| + | |||
| + | === Le résultat == | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | On obtient un objet '' | ||
| + | * args : les arguments fournis pour exécuter le processus | ||
| + | * returncode : exit status of child process, typiquement 0 si tout s'est bien passé | ||
| + | * stdout : les données issues du process, en string ou byte selon le paramètre text=True (string) ou False (byte) | ||
| + | * stderr : idem pour la sortie d' | ||
| + | |||
| + | === Cas d'une commande via ssh === | ||
| + | |||
| + | Admettons que l'on souhaite exécuter une commande via ssh sur une machine distante, par exemple '' | ||
| + | |||
| + | Malgré la présence de guillemets ''" | ||
| + | En revanche, toute la commande distante est dans le même argument de subprocess.run(). ça donne : | ||
| + | |||
| + | <code python> | ||
| + | subprocess.run([" | ||
| + | # on peut rajouter les options capture_output=True, | ||
| + | </ | ||
| + | |||
| + | ===== Popen, la fonction à la base ===== | ||
| + | |||
| + | '' | ||
| + | |||
| + | === communicate() === | ||
| + | [[https:// | ||
| + | '' | ||
| + | |||
| + | communicate() returns a tuple (stdout_data, | ||
| + | |||
| + | Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other than None in the result tuple, you need to give stdout=PIPE and/or stderr=PIPE too. | ||
| + | |||
| + | Timeout est donné en seconde. Si le processus n'est pas fini avant la fin du timeout, lève une exception '' | ||
| + | |||
| + | Le returncode est disponible sur l' | ||
| + | |||
| + | === Exemples avec Popen() === | ||
| + | |||
| + | <code python> | ||
| + | # -- Interagir avec les entrées / sorties -- # | ||
| + | |||
| + | # EXEMPLE | ||
| + | from subprocess import Popen, PIPE | ||
| + | process = Popen([" | ||
| + | stdout, stderr = process.communicate(input=" | ||
| + | print(stdout) | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | <code python> | ||
| + | # redirection des entrées et sorties | ||
| + | with open(" | ||
| + | f.write(" | ||
| + | |||
| + | with open(" | ||
| + | process = Popen([" | ||
| + | </ | ||
| + | |||
| + | <code python> | ||
| + | # Interagir avec les entrées / sorties | ||
| + | |||
| + | import subprocess | ||
| + | process1 = subprocess.Popen([' | ||
| + | process2 = subprocess.Popen([' | ||
| + | |||
| + | # Write data to the input of the first process | ||
| + | process1.stdin.write(b' | ||
| + | process1.stdin.close() | ||
| + | |||
| + | # Get the output of the second process | ||
| + | output = process2.communicate()[0] | ||
| + | |||
| + | # Print the output (ici en format byte et non string, car pas de text=True) | ||
| + | print(output.decode()) | ||
| + | </ | ||
| + | |||
| + | <code python> | ||
| + | # -- Gérer les erreurs et exceptions -- # | ||
| + | import subprocess | ||
| + | try: | ||
| + | process1 = subprocess.Popen([' | ||
| + | process2 = subprocess.Popen([' | ||
| + |  | ||
| + | # Get the output of the second process | ||
| + | output = process2.communicate()[0] | ||
| + |  | ||
| + | # Print the output | ||
| + | print(output.decode()) | ||
| + |  | ||
| + | # Check the return code of each process | ||
| + | if process1.returncode != 0: | ||
| + | raise subprocess.CalledProcessError(process1.returncode, | ||
| + | if process2.returncode != 0: | ||
| + | raise subprocess.CalledProcessError(process2.returncode, | ||
| + |  | ||
| + | except subprocess.CalledProcessError as e: | ||
| + | print(f" | ||
| + | </ | ||
| + | |||
| + | === le paramètre shell=False/ | ||
| + | |||
| + | Le paramètre '' | ||
| + | * True : La commande est exécutée au sein d'un nouveau shell. Cela permet l' | ||
| + | * False : La commande est exécutée directement sans invoquer un shell, les arguments sont fournis comme éléments d'une liste :  '' | ||
| + | |||
| + | ===== Cas d' | ||
| + | |||
| + | Note : le premier processus ne peut être exécuté avec '' | ||
| + | |||
| + | |||
| + | <code python> | ||
| + | # -- Enchainer les entrées et sorties -- # | ||
| + | |||
| + | ## EXEMPLE 1 | ||
| + | import subprocess | ||
| + | p1 = subprocess.Popen([" | ||
| + | result = subprocess.run([" | ||
| + | print(" | ||
| + | print(" | ||
| + | |||
| + | |||
| + | ## EXEMPLE 2 | ||
| + | import subprocess | ||
| + | ls_process = subprocess.Popen([" | ||
| + | grep_process = subprocess.Popen([" | ||
| + | |||
| + | output, error = grep_process.communicate() | ||
| + | print(output) | ||
| + | print(error) | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== Les autres fonctions de haut niveau ===== | ||
| + | [[https:// | ||
| + | |||
| + | Pour des usages facilités, le module '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
