Я хочу використовувати 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)