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 '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||