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 subprocess
module, 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 ps
et grep
sé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.find
sur la sortie.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
signifie 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 output
variable
string.find
, ce qui a été déprécié en faveur str.find
(c'est-à-dire la méthode find
sur les str
objets).
grep
décède prématurément; ps
peut 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.
communicate
est 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 .