Я хочу использовать subprocess.check_output()
с ps -A | grep 'process_name'
. Я пробовал разные решения, но пока ничего не получалось. Кто-нибудь может подсказать мне, как это сделать?
Я хочу использовать subprocess.check_output()
с ps -A | grep 'process_name'
. Я пробовал разные решения, но пока ничего не получалось. Кто-нибудь может подсказать мне, как это сделать?
Ответы:
Чтобы использовать трубу с 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
на выходе.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
просто означает, что grep ничего не нашел, так что это нормальное поведение.
ps.wait()
когда у нас уже есть выход. ps.wait.__doc__
ждет, когда ребенок завершит свою работу, но содержание ребенка, кажется, уже помещено в output
переменную
string.find
, который устарел в пользу str.find
(то есть, метод find
на str
объектах).
grep
умирает преждевременно; ps
может зависать на неопределенный срок, если он выдает достаточно данных, чтобы заполнить свой буфер канала ОС (потому что вы не вызвали ps.stdout.close()
родительский буфер ). Поменяйте местами стартовый порядок, чтобы избежать этого
Или вы всегда можете использовать метод связи для объектов подпроцесса.
cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
Метод связи возвращает кортеж стандартного вывода и стандартную ошибку.
communicate
лучше, чем wait
. Существует такое предупреждение: «Это приведет к взаимоблокировке при использовании stdout = PIPE и / или stderr = PIPE, и дочерний процесс генерирует достаточно данных для канала, так что он блокирует ожидание буфера канала ОС для приема большего количества данных. Используйте Communication () для избегай этого.
См. Документацию по настройке конвейера с использованием подпроцесса: 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]
Решение 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)