Je veux utiliser subprocess.check_output()avec ps -A | grep 'process_name'. J'ai essayé différentes solutions mais jusqu'à présent, rien n'a fonctionné. Quelqu'un peut-il me guider comment le faire?
Je veux utiliser subprocess.check_output()avec ps -A | grep 'process_name'. J'ai essayé différentes solutions mais jusqu'à présent, rien n'a fonctionné. Quelqu'un peut-il me guider comment le faire?
Réponses:
Pour utiliser un tuyau avec le subprocessmodule, vous devez passer shell=True.
Cependant, ce n'est pas vraiment conseillé pour diverses raisons, dont la sécurité n'est pas la moindre. Au lieu de cela, créez les processus pset grepséparément et 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 est d'appeler subprocess.check_output(('ps', '-A'))puis str.findsur la sortie.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1signifie simplement que rien n'a été trouvé par grep, c'est donc un comportement normal.
ps.wait()pour quand nous avons déjà la sortie. ps.wait.__doc__attend la fin de l'enfant mais le contenu de l'enfant semble déjà placé dans la outputvariable
string.find, ce qui a été déprécié en faveur str.find(c'est-à-dire la méthode findsur les strobjets).
grepdécède prématurément; pspeut se bloquer indéfiniment s'il produit suffisamment de sortie pour remplir son tampon de tuyau OS (car vous n'avez pas appelé ps.stdout.close()le parent). Échangez l'ordre de départ, pour l'éviter
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 renvoie un tuple de la sortie standard et l'erreur standard.
communicateest meilleure que wait. Il y a un tel avertissement: "Cela bloquera lors de l'utilisation de stdout = PIPE et / ou stderr = PIPE et le processus enfant génère suffisamment de sortie vers un canal de telle sorte qu'il bloque l'attente de la mémoire tampon du canal du système d'exploitation pour accepter plus de données. Utilisez communic () pour éviter cela. "
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 il 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]
La solution JKALAVIS est bonne, mais j'ajouterais une amélioration pour utiliser shlex au lieu de SHELL = TRUE. ci-dessous im grepping out Query times
#!/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)
Après Python 3.5, vous pouvez également utiliser:
import subprocess
f = open('test.txt', 'w')
process = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, universal_newlines=True)
f.write(process.stdout)
f.close()
L'exécution de la commande est bloquante et la sortie sera dans process.stdout .