434 votes

Assigner la sortie de os.system à une variable et l'empêcher d'être affichée à l'écran

Je veux assigner la sortie d'une commande que je lance en utilisant os.system à une variable et l'empêcher d'être affichée à l'écran. Mais, dans le code ci-dessous ,la sortie est envoyée à l'écran et la valeur imprimée pour la variable var est 0, ce qui signifie, je suppose, que la commande s'est exécutée avec succès ou non. Existe-t-il un moyen d'affecter la sortie de la commande à la variable et d'empêcher son affichage à l'écran ?

var = os.system("cat /etc/services")
print var #Prints 0

8 votes

N'utilisez pas os.system (ni os.popen (selon la réponse que vous avez acceptée) : utiliser subprocess.Popen c'est chemin mieux !

1 votes

@AlexMartelli, on ne peut pas utiliser une commande complexe (par exemple piped) dans subprocess.Popen(), mais avec os.system on peut

2 votes

@vak, bien sûr vous pouvez utiliser des pipes &c w/ subprocess.Popen -- ajoutez simplement shell=True !

648voto

Chris Bunch Points 25857

De " Equivalent des backticks de Bash en Python ", ce que j'ai demandé il y a longtemps, ce que vous pouvez utiliser c'est popen :

os.popen('cat /etc/services').read()

De la Documentation pour Python 3.6 ,

Ceci est implémenté en utilisant subprocess.Popen ; voir la documentation de cette classe de cette classe pour des moyens plus puissants de gérer et de communiquer avec les sous-processus.


Voici le code correspondant pour subprocess :

import subprocess

proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

7 votes

Notez que Walter subprocess.check_output est plus proche de la solution Pythonique en une ligne que vous semblez rechercher, tant que vous ne vous souciez pas de stderr .

13 votes

@ChrisBunch Pourquoi suprocess est une meilleure solution que os.popen ?

6 votes

Vous ne devriez (presque) jamais utiliser shell=True . Voir docs.python.org/3/library/

237voto

Walter Mundt Points 9160

Vous pouvez également consulter le subprocess qui a été construit pour remplacer toute la famille des modules Python popen -appels de type.

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)

L'avantage de ce système est qu'il offre une grande flexibilité quant à la manière d'invoquer les commandes, à l'endroit où les flux d'entrée/sortie/erreur standard sont connectés, etc.

3 votes

Note, check_output a été ajouté avec python 2.7 docs.python.org/2.7/library/

3 votes

Ajouter stderr=subprocess.STDOUT pour capturer également les erreurs standard

3 votes

J'ai utilisé cette méthode avec systeminfo commande. La sortie était quelque chose comme méchant comme ceci b'\r\nHost Name: DIMUTH-LAPTOP\r\nOS Name: Microsoft Windows 10 Pro\r\nOS Version: 10.0.10240 N/A Build 10240\r\nOS Manufacturer: Microsoft Corporation

48voto

ianmclaury Points 624

Le module de commandes est un moyen de faire cela à un niveau assez élevé :

import commands
status, output = commands.getstatusoutput("cat /etc/services")

status est 0, la sortie est le contenu de /etc/services.

61 votes

Citant le documentation du module de commandes : "Déprécié depuis la version 2.6 : le module commands a été supprimé dans Python 3. Utilisez le module subprocess à la place." .

7 votes

C'est vrai que c'est dépassé, mais parfois, on veut juste faire quelque chose rapidement et facilement en quelques lignes de code.

7 votes

@advocate vérifiez la commande check_output du subprocess. C'est rapide, facile, et ne se dépréciera pas de sitôt !

43voto

Chiel92 Points 2362

Pour python 3.5+, il est recommandé d'utiliser la fonction exécuter la fonction du module de sous-processus . Cela renvoie un CompletedProcess à partir duquel vous pouvez facilement obtenir la sortie ainsi que le code de retour. Puisque vous n'êtes intéressé que par la sortie, vous pouvez écrire un utilitaire enveloppant comme ceci.

from subprocess import PIPE, run

def out(command):
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
    return result.stdout

my_output = out("echo hello world")
# Or
my_output = out(["echo", "hello world"])

35voto

Vasili Syrakis Points 3355

Je sais que la réponse à cette question a déjà été donnée, mais je voulais partager avec vous une façon potentiellement plus agréable d'appeler Popen en utilisant la fonction from x import x et fonctions :

from subprocess import PIPE, Popen

def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]

print cmdline("cat /etc/services")
print cmdline('ls')
print cmdline('rpm -qa | grep "php"')
print cmdline('nslookup google.com')

2 votes

3 ans plus tard, voici ce qui a fonctionné pour moi. J'ai mis ça dans un fichier séparé appelé cmd.py et ensuite, dans mon fichier principal, j'ai écrit from cmd import cmdline et l'utilisait en cas de besoin.

1 votes

J'avais le même problème avec os.system returning 0, mais j'ai essayé cette méthode et ça marche très bien ! Et en prime, c'est joli et bien rangé :) Merci !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X