Я хочу використовувати 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
просто означає, що греп нічого не знайшов, тому це нормальна поведінка.
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, і дочірній процес генерує достатній вихід на трубу, щоб заблокувати очікування, коли буфер труб ОС прийме більше даних. Використовуйте зв'язок () для уникати цього ".
Дивіться документацію щодо налаштування трубопроводу за допомогою підпроцесу: 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 = ІСТИНА. нижче імпортування разів запитів
#!/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)