Python

Comment exécuter des commandes Shell en Python à l'aide de la méthode d'exécution de sous-processus

Comment exécuter des commandes Shell en Python à l'aide de la méthode d'exécution de sous-processus
Subprocess est un module Python intégré qui peut être utilisé pour créer de nouveaux processus et interagir avec leurs flux de données d'entrée et de sortie. En termes plus simples, vous pouvez l'utiliser pour exécuter des commandes shell et exécuter des binaires exécutables généralement dispersés dans divers dossiers "bin" sur un système de fichiers Linux. Vous pouvez également fournir un chemin complet vers un binaire exécutable et utiliser n'importe quel commutateur de ligne de commande associé au binaire. Cet article explique comment utiliser le module de sous-processus et sa méthode d'exécution dans les applications Python. Tous les exemples de code de l'article sont testés avec Python 3.8.2 sur Ubuntu 20.04.

Le sous-processus.exécuter la méthode

Le sous-processus.La méthode run prend une liste d'arguments. Lorsque la méthode est appelée, elle exécute la commande et attend la fin du processus, renvoyant à la fin un objet "CompletedProcess". L'objet "CompletedProcess" renvoie stdout, stderr, les arguments d'origine utilisés lors de l'appel de la méthode et un code de retour. Stdout fait référence au flux de données produit par la commande, tandis que stderr fait référence à toutes les erreurs générées lors de l'exécution du programme. Tout code de retour différent de zéro (code de sortie) signifierait une erreur avec la commande exécutée dans le sous-processus.méthode d'exécution.

Exemple 1 : Contenu de sortie d'un fichier texte à l'aide du sous-processus.exécuter la méthode

La commande ci-dessous affichera le contenu d'un "data.txt", en supposant qu'il contienne une chaîne "name=John".

sous-processus d'importation
sous-processus.run(["chat", "données.SMS"])

L'exécution du code ci-dessus renverra la sortie suivante :

nom=Jean
CompletedProcess(args=['cat', 'data.txt'], code retour=0)

Le premier élément de l'argument liste est le nom de la commande à exécuter. Tout élément de la liste qui suit le premier élément est considéré comme une option ou un commutateur de ligne de commande. Vous pouvez également utiliser des tirets simples et doubles pour définir les options. Par exemple, pour répertorier les fichiers et dossiers dans un répertoire, le code serait "sous-processus.run(["ls", "-l"]". Dans la plupart de ces cas, vous pouvez considérer n'importe quel argument séparé par des espaces dans une commande shell comme un élément individuel dans la liste fournie au sous-processus.méthode d'exécution.

Exemple 2 : Supprimer la sortie du sous-processus.exécuter la méthode

Pour supprimer la sortie du sous-processus.run méthode, vous devrez fournir "stdout=subprocess.DEVNULL" et "stderr=sous-processus.DEVNULL" comme arguments supplémentaires.

sous-processus d'importation
sous-processus.run(["chat", "données.txt"], stdout=sous-processus.DEVNULL,
stderr=sous-processus.DEVNULL)

L'exécution du code ci-dessus produira la sortie suivante :

CompletedProcess(args=['cat', 'data.txt'], code retour=0)

Exemple 3 : Capturer la sortie du sous-processus.exécuter la méthode

Pour capturer la sortie du sous-processus.run méthode, utilisez un argument supplémentaire nommé "capture_output=True".

sous-processus d'importation
sortie = sous-processus.run(["chat", "données.txt"], capture_output=True)
impression (sortie)

L'exécution du code ci-dessus produira la sortie suivante :

CompletedProcess(args=['cat', 'data.txt'], code retour=0,
stdout=b'nom=Jean\n', stderr=b")

Vous pouvez accéder individuellement aux valeurs stdout et stderr en utilisant "output.stdout" et "sortie.méthodes "stderr". La sortie est produite sous la forme d'une séquence d'octets. Pour obtenir une chaîne en sortie, utilisez "output.sortie standard.méthode decode ("utf-8")". Vous pouvez également fournir "text=True" comme argument supplémentaire au sous-processus.exécuter l'appel pour obtenir la sortie au format chaîne. Pour obtenir le code d'état de sortie, vous pouvez utiliser la "sortie.méthode returncode".

Exemple 4 : lever une exception en cas d'échec d'une commande exécutée par un sous-processus.exécuter la méthode

Pour lever une exception lorsque la commande se termine avec un statut différent de zéro, utilisez l'argument « check=True ».

sous-processus d'importation
sous-processus.run(["chat", "données.tx"], capture_output=True, text=True, check=True)

L'exécution du code ci-dessus produira la sortie suivante :

augmenter CalledProcessError(retcode, traiter.arguments,
sous-processus.CalledProcessError : commande '['cat', 'data.tx']'
a renvoyé l'état de sortie 1 différent de zéro.

Exemple 5 : passer une chaîne à la commande exécutée par le sous-processus.exécuter la méthode

Vous pouvez passer une chaîne à la commande à exécuter par sous-processus.exécuter la méthode en utilisant l'argument "input='string'".

sous-processus d'importation
sortie = sous-processus.run(["chat"], input="données.txt", capture_output=True,
text=True, check=True)
impression (sortie)

L'exécution du code ci-dessus produira la sortie suivante :

CompletedProcess(args=['cat'], returncode=0, stdout="data.txt", stderr=")

Comme vous pouvez le voir, le code ci-dessus passe « data.txt" en tant que chaîne et non en tant qu'objet fichier. Pour transmettre des « données.txt" en tant que fichier, utilisez l'argument "stdin".

avec open("données.txt") comme f :
sortie = sous-processus.run(["cat"], stdin=f, capture_output=True,
text=True, check=True)
impression (sortie)

L'exécution du code ci-dessus produira la sortie suivante :

CompletedProcess(args=['cat'], returncode=0, stdout="name=John\n", stderr=")

Exemple 6 : Exécuter la commande directement dans le shell à l'aide du sous-processus.exécuter la méthode

Il est possible d'exécuter une commande directement dans un shell "en l'état", au lieu d'utiliser une division de chaîne dans la commande principale et les options qui la suivent. Pour ce faire, vous devez passer "shell=True" comme argument supplémentaire. Ceci est cependant déconseillé par les développeurs python car l'utilisation de "shell=True" peut entraîner des problèmes de sécurité. Vous pouvez en savoir plus sur les implications en matière de sécurité ici.

sous-processus d'importation
sous-processus.run("cat 'données.txt'", shell=True)

L'exécution du code ci-dessus produira la sortie suivante :

nom=Jean

Conclusion

Le sous-processus.La méthode run en Python est assez puissante, car elle vous permet d'exécuter des commandes shell dans python lui-même. Cela aide à limiter tout le code à python lui-même sans avoir besoin d'avoir du code de script shell supplémentaire dans des fichiers séparés. Cependant, il peut être assez difficile de tokeniser correctement les commandes shell dans une liste python. Vous pouvez utiliser le "shlex.split ()" pour tokeniser les commandes shell simples, mais dans les commandes longues et complexes - en particulier celles avec des symboles de tuyau - shlex ne parvient pas à diviser correctement la commande. Dans de tels cas, le débogage peut être un problème délicat. Vous pouvez utiliser l'argument "shell=True" pour éviter cela, mais il existe certains problèmes de sécurité associés à cette action.

Meilleures applications de mappage de manette de jeu pour Linux
Si vous aimez jouer à des jeux sur Linux avec une manette de jeu au lieu d'un système de saisie clavier et souris typique, il existe des applications ...
Outils utiles pour les joueurs Linux
Si vous aimez jouer à des jeux sur Linux, il est probable que vous ayez utilisé des applications et des utilitaires comme Wine, Lutris et OBS Studio p...
Jeux HD remasterisés pour Linux qui n'ont jamais eu de version Linux plus tôt
De nombreux développeurs et éditeurs de jeux proposent une remasterisation HD d'anciens jeux pour prolonger la durée de vie de la franchise, veuillez ...