web-dev-qa-db-fra.com

Comment utiliser la commande `subprocess` avec des pipes

Je veux utiliser subprocess.check_output() avec ps -A | grep 'process_name'. J'ai essayé diverses solutions mais jusqu'à présent, rien n'a fonctionné. Est ce que quelqu'un peut me guider comment le faire?

198
zuberuber

Pour utiliser un tuyau avec le module subprocess, vous devez passer Shell=True.

Cependant, cela n'est pas vraiment conseillé pour diverses raisons, notamment la sécurité. Au lieu de cela, créez les processus ps et grep séparément, puis dirigez la sortie de l'un vers l'autre, comme suit:

ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()

Dans votre cas particulier, cependant, la solution simple consiste à appeler subprocess.check_output(('ps', '-A')) puis str.find sur la sortie.

372
Taymon

Ou vous pouvez toujours utiliser la méthode de communication sur les objets de sous-processus.

cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,Shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print output

La méthode de communication retourne un tuple de la sortie standard et de l'erreur standard.

51
jkalivas

Voir la documentation sur la configuration d'un pipeline à l'aide d'un sous-processus: http://docs.python.org/2/library/subprocess.html#replacing-Shell-pipeline

Je n'ai pas testé l'exemple de code suivant mais cela devrait être à peu près ce que vous voulez:

query = "process_name"
ps_process = Popen(["ps", "-A"], stdout=PIPE)
grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)
ps_process.stdout.close()  # Allow ps_process to receive a SIGPIPE if grep_process exits.
output = grep_process.communicate()[0]
20
AlcubierreDrive

Essayez également d’utiliser la commande 'pgrep' au lieu de 'ps -A | grep 'process_name'

3
Shooe

La solution JKALAVIS est bonne, mais j'ajouterais une amélioration consistant à utiliser shlex au lieu de Shell = TRUE. ci-dessous im grepping out temps de requête

#!/bin/python
import subprocess
import shlex

cmd = "Dig @8.8.4.4 +notcp www.google.com|grep 'Query'"
ps = subprocess.Popen(cmd,Shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print output

À votre santé,

3
Daniel Smith

Vous pouvez essayer la fonctionnalité de pipe dans sh.py :

import sh
print sh.grep(sh.ps("-ax"), "process_name")
3
amoffat