LINUX.ORG.RU

select в питоне

 ,


1

3

Всем привет :)

есть такой отрывок питоновского говнокода:

    p = subprocess.Popen(cmd.split(' '),
                         stdout = subprocess.PIPE,
                         stdin  = subprocess.PIPE,
                         stderr = subprocess.PIPE)

    while True:
        (r, w, e) = select.select([ p.stdout ], [], [], 1)

        print('dbg >>>', r)
        print(p.stdout.readline())
        print('state: ', state)
        print('r:', r)
        print('dbg <<<')

        if not r and state == 0:
            continue

        if not r and state == 1:
            p.kill()
            last_record = line['date']
            return total, first_record, last_record

        line = json.loads(p.stdout.readline())
        
        if line:
            state = 1

в переменной cmd такое:

    cmd = 'ssh root@{0} tailf -n100 {1}'.format('localhost',
           '{0}/conf/rtls.log'.format(ROOTDIR))

Хочется, такое: если в течение 3-х секунд нет никакого выхлопа, делать return



Последнее исправление: ubik (всего исправлений: 1)
Ответ на: комментарий от true_admin

проблема в том, что код не выходит из while цикла

ubik
() автор топика

ЕМНИП select срабатывает как только есть данные или по таймауту. Если сработал по таймауту, то списки (r, w и e) будут пустыми. Другими словами в select нужно поставить таймаут три секунды и если списки пустые - делать return.

AlexKiriukha ★★★★
()
Ответ на: комментарий от AlexKiriukha

данные получаются, с этим всё ок, но как только последняя строка прочитана из лупа всё равно не выходит. У меня стоит таймаут в 1 секунду сейчас, но проблема не в этом.

ubik
() автор топика
Ответ на: комментарий от ubik

У тебя в коде есть бесконечный цикл и ни одного break. Ну и код написан так что до return никогда не доходит. Панымаишь? Ж)

true_admin ★★★★★
()

С блокирующими вызовами я юзаю обычно что-то вроде

import signal
import time

# use SIGALARM to detect a timeout
def handler(signum, frame):
    # raise user exception to process in main loop
    raise UserWarning
    
while True:

    try:
        # set the signal handler and alarm
        signal.signal(signal.SIGALRM, handler)
        signal.alarm(3)

        # Do something blocking here
        print "Blocking"
        time.sleep (60)
        print "Blocking done"

        # disable the alarm
        signal.alarm(0)


    except UserWarning:
        # SIGALARM, gpsd read timeout, fail
        print "Timeout"
alx777 ★★
()
Ответ на: комментарий от true_admin

да, я идиот. Проблема была в этом куске:

print(p.stdout.readline())
Вот тут ожидается поток, которого нет в случае, если я достиг конца файла.

Всем спасибо :)

ubik
() автор топика

Вообще, если не нужен win (а вариант с селектом там всё равно не сработает), то есть ещё pexpect. Специально для таких дел придуманный фреймворчег, с ассёртами и дружбой с тестами.

pon4ik ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.