2009-09-10 11 views
1

J'ai commande comme ceci.Comment obtenir la sortie de commande externe combiner avec Pipe

wmctrl -lp | awk '/gedit/ { print $1 }' 

Et je veux sa sortie dans le script python, j'ai essayé ce code

>>> import subprocess 
>>> proc = subprocess.Popen(["wmctrl -lp", "|","awk '/gedit/ {print $1}"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
>>> proc.stdout.readline() 
'0x0160001b -1 6504 beer-laptop x-nautilus-desktop\n' 
>>> proc.stdout.readline() 
'0x0352f117 0 6963 beer-laptop How to get output from external command combine with Pipe - Stack Overflow - Chromium\n' 
>>> proc.stdout.readline() 
'0x01400003 -1 6503 beer-laptop Bottom Expanded Edge Panel\n' 
>>> 

Il semble que mon code est faux que wmctrl -lp était exécuter et | awk '{print $1}' est omis Ma attendre la sortie aimerait 0x03800081

$ wmctrl -lp | awk '/gedit/ {print $1}' 
0x03800081 

Est-ce que quelqu'un vous aide?

Répondre

7

Avec shell=True, vous devez utiliser une seule ligne de commande au lieu d'un tableau, sinon vos arguments supplémentaires sont interprétés comme des arguments shell. De l'subprocess documentation:

Sur Unix, avec shell = True: Si args est une chaîne, elle spécifie la chaîne de commande à exécuter à travers la coque. Si args est une séquence, le premier élément spécifie la chaîne de commande, et tous les éléments supplémentaires seront traités comme des arguments shell supplémentaires.

donc votre appel devrait être:

subprocess.Popen("wmctrl -lp | sed /gedit/ '{print $1}'", shell=True, ... 

Je pense que vous pouvez avoir un guillemet simple déséquilibre là-dedans.

0

Parce que vous passez une séquence dans le programme, il pense que la conduite est un argument -wmcrtrl, comme si vous avez

wmctrl -lp "|" 

et donc la conduite réelle opération est perdue .

Faire une seule chaîne devrait en effet vous donner le résultat correct:

>>> import subprocess as s 
>>> proc = s.Popen("echo hello | grep e", shell=True, stdout=s.PIPE, stderr=s.PIPE) 
>>> proc.stdout.readline() 
'hello\n' 
>>> proc.stdout.readline() 
'' 
0

Après quelques recherches, j'ai le code suivant qui fonctionne très bien pour moi. Il imprime à la fois stdout et stderr en temps réel. J'espère que cela aidera quelqu'un d'autre qui en a besoin. En cas de besoin, je pense qu'il est facile de collecter la sortie ou l'erreur dans une chaîne et de revenir en arrière.

Questions connexes