web-dev-qa-db-fra.com

lire un os.popen (commande) dans une chaîne

Je ne suis pas sûr que mon titre soit correct. Ce que je fais, c'est écrire un script python pour automatiser l'écriture de mon code. Je suis donc en train de parcourir un fichier .h . mais je souhaite développer toutes les macros avant de commencer. et je souhaite donc appeler le shell pour:

gcc -E myHeader.h

Ce qui devrait sortir la version post-prétraitée de myHeader.h sur stdout. Maintenant, je veux lire toute cette sortie directement dans une chaîne pour un traitement ultérieur. J'ai lu que je peux le faire. avec popen, mais je n'ai jamais utilisé d'objets pipe.

comment puis-je faire cela? 

14
Lyndon White

La fonction os.popen renvoie simplement un objet de type fichier. Vous pouvez l'utiliser comme ceci:

import os

process = os.popen('gcc -E myHeader.h')
preprocessed = process.read()
process.close()

Comme d’autres l’ont dit, vous devriez utiliser subprocess.Popen. Il est conçu pour être une version plus sûre de os.popen. Les documents Python ont une section décrivant comment basculer .

23
Brian McKenna
import subprocess

p = subprocess.popen('gcc -E myHeader.h'.split(),
                     stdout=subprocess.PIPE)
preprocessed, _ = p.communicate()

Chaîne preprocessed a maintenant la source prétraitée dont vous avez besoin - et vous avez utilisé la "bonne" manière (moderne) de passerelle à un sous-processus, plutôt que l'ancien os.popen.

16
Alex Martelli

vous devriez utiliser subprocess.Popen() il y a de nombreux exemples sur SO

Comment obtenir une sortie de subprocess.Popen ()

5
John La Rooy

Le os.popen () est déconseillé depuis Python 2.6. Vous devez maintenant utiliser le module subprocess à la place: http://docs.python.org/2/library/subprocess.html#subprocess.Popen

import subprocess

command = "gcc -E myHeader.h"  # the Shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, Shell=True)

#Launch the Shell command:
output = process.communicate()

print output[0]

Dans le constructeur Popen, si Shell est True , vous devez transmettre la commande sous forme de chaîne plutôt que sous forme de séquence. Sinon, divisez simplement la commande en une liste: 

command = ["gcc", "-E", "myHeader.h"]  # the Shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)

Si vous devez également lire l'erreur standard, dans l'initialisation de Popen, vous pouvez définir stderr sur sous-processus.PIPE ou sur sous-processus.STDOUT :

import subprocess

command = "gcc -E myHeader.h"  # the Shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, Shell=True)

#Launch the Shell command:
output, error = process.communicate()
1
Paolo Rovelli

Voici une autre approche qui capture à la fois la sortie normale et la sortie d'erreur:

com_str = 'uname -a'
command = subprocess.Popen([com_str], stdout=subprocess.PIPE, Shell=True)
(output, error) = command.communicate()
print output

Linux 3.11.0-20-generic  Fri May 2 21:32:55 UTC 2014 GNU/Linux

et

com_str = 'id'
command = subprocess.Popen([com_str], stdout=subprocess.PIPE, Shell=True)
(output, error) = command.communicate()
print output

uid=1000(myname) gid=1000(myGID) groups=1000(mygrp),0(root)
0
SDsolar