Убейте дочерний процесс, когда вывод дочернего процесса удовлетворяет условию? - PullRequest
0 голосов
/ 10 января 2019

Я хочу, чтобы Python убил этот процесс, если выходные данные дочернего процесса соответствуют критериям

Например, это бесконечный цикл while_file.py, он печатает от 0 до 999 и выглядит так, что ответа нет.

i = 0
while 1:
    if i < 1000:
        print i
    i += 1

Я хочу проверить, равен ли вывод дочернего процесса 999, а затем уничтожить его.

import os
import signal
import subprocess

def run_cmd(cmd):
    pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True, preexec_fn=os.setsid)
    while True:
        r = pro.stdout.read()
        print r
        if r == 999:
            os.killpg(os.getpgid(pro.pid), signal.SIGTERM)

if __name__=='__main__':
    print run_cmd('python while_file.py')

Но, похоже, нет ответа ... почему? Это заблокировано?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Есть несколько проблем:

  • Функция «чтение» (из pro.stoud.read) читает весь файл (до EOF). Что в вашем случае не будет работать, потому что stdout никогда не бывает близко, что означает отсутствие EOF. Вы должны использовать readline
  • когда вы читаете, вы читаете строки, а не числа (поэтому вы должны сравнить с "999", а не с 999)
  • Я бы порекомендовал удостовериться, что буферизация отсутствует (может стать неприятной позже, если что-то останется в буфере)

Измененные коды:

import sys

i = 0
while True:
    if i < 1000:
        print i
        sys.stdout.flush()
    i += 1

и

import os
import signal
import subprocess

def run_cmd(cmd):
    pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True, preexec_fn=os.setsid)
    while True:
        r = pro.stdout.readline()
        r = r.strip()
        print(r)
        if r == "999":
            os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
            print("Process killed")
            break

if __name__=='__main__':
    print run_cmd('PYTHONUNBUFFERED=1; python a.py')
0 голосов
/ 10 января 2019

Я не знаю, хорошая это идея или нет, но вот способ, которым вы можете это сделать:

while_file.py

i = 0
while 1:
    if i < 1000:
        print(i)
        i += 1

stackoverflow.py

import os
import signal
import subprocess

def run_cmd(cmd):
    pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    for line in iter(pro.stdout.readline, ''):
        r = line.rstrip()
        print(r)
        if r == b'999':
            os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
            print("True !")

if __name__ == '__main__':
    print(run_cmd('python while_file.py'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...