it-roy-ru.com

Как использовать команду `subprocess` с каналами

Я хочу использовать subprocess.check_output() с ps -A | grep 'process_name'. Я пробовал разные решения, но пока ничего не получалось. Кто-нибудь может подсказать мне, как это сделать?

186
zuberuber

Чтобы использовать канал с модулем subprocess, вы должны передать Shell=True.

Однако это не рекомендуется по разным причинам, не в последнюю очередь из-за безопасности. Вместо этого создайте процессы ps и grep отдельно и перенаправьте выходные данные из одного в другой, например, так:

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

Однако в вашем конкретном случае простое решение заключается в вызове subprocess.check_output(('ps', '-A')), а затем str.find на выходе.

360
Taymon

Или вы всегда можете использовать метод связи для объектов подпроцесса.

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

Метод связи возвращает кортеж стандартного вывода и стандартную ошибку.

50
jkalivas

См. Документацию по настройке конвейера с использованием подпроцесса: http://docs.python.org/2/library/subprocess.html#replacing-Shell-pipeline

Я не тестировал следующий пример кода, но он должен быть примерно таким, как вы хотите:

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

Кроме того, попробуйте использовать команду 'pgrep' вместо 'ps -A | grep 'process_name'

3
Shooe

Решение JKALAVIS - это хорошо, но я бы добавил улучшение, чтобы использовать shlex вместо Shell = TRUE. ниже я вытащил время запроса

#!/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

Ура,

3
Daniel Smith

Вы можете попробовать функциональность канала в sh.py :

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