Python: запустите файл bach и прочитайте вывод, пока не появится определенная строка, и продолжите

Итак, у меня есть batch файл, который запускает appium сервер.

Когда я начинаю выполнять свой batch файл, я хочу прочитать вывод, а когда server работает, я хочу продолжить.

Я знаю, когда appium сервер работает из этого вывода:

Appium REST http interface listener started on 0.0.0.0:4723

На данный момент это то, что у меня есть:

process = subprocess.Popen([r'C:\\appium.bat'])
stdout = process.communicate()[0]
print('STDOUT:{}'.format(stdout))

Я хочу подождать до 60 секунд или до появления этой строки. В случае, если прошло 60 секунд, а эта строка (Appium REST http interface listener started on 0.0.0.0:4723) не появилась, я хочу поднять exception.

Моя проблема в том, что когда мой сервер запускается, процесс продолжает работать, поэтому он никогда не выходит и не переходит к следующему коду, и я не могу убить процесс appium.

Любые предложения, как это решить?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
287
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете подождать, используя модуль времени

import time

time.sleep(60) # wait for 60 seconds

Но как я могу выйти, когда я получил нужную строку? я не могу убить процесс appium, потому что я хочу его использовать

falukky 08.04.2019 15:18

Вы можете сделать это с помощью signal.alarm,

import signal
import time
import subprocess

def handler(signum, stack):
    raise Exception("It didn't happen in time...") # raise exception if it didn't come up within the time frame 

signal.signal(signal.SIGALRM, handler)
signal.alarm(60)
process = subprocess.Popen([r'C:\\appium.bat'])
stdout = process.communicate()[0] # assuming this blocks
print('STDOUT:{}'.format(stdout))
signal.alarm(0) # turn of the alarm, if it came up within 60 seconds

если .communicate() не blocking, то,

import subprocess
process = subprocess.Popen([r'C:\\appium.bat'])
stdout = process.communicate()[0] # non blocking ?
print('STDOUT:{}'.format(stdout))
time.sleep(60)
if 'Appium REST http interface listener started' not in stdout:
    raise Exception("It didn't come up in time...")

Я немного запутался, где именно мне нужно использовать этот код и как?

falukky 08.04.2019 15:22

@falukky Я предполагаю, что .communicate() будет блокироваться, пока не появится REST API?

han solo 08.04.2019 15:24

В настоящее время мой код печатает вывод процесса, и потому что процесс, который его запускает, никогда не продолжается, и вы вылетаете из кода в этой строке: signal.signal (signal.SIGALRM, обработчик)

falukky 08.04.2019 15:39

Что написано в crash ?

han solo 08.04.2019 15:52

AttributeError: модуль «сигнал» не имеет атрибута «SIGALRM»

falukky 08.04.2019 15:54

@фалукки import signal; print(signal.SIGALRM). Не должно падать :/

han solo 08.04.2019 15:56

print(signal.SIGALRM) дал вам AttributeError ?

han solo 08.04.2019 16:01

Кстати, я использую Python 3.x

falukky 08.04.2019 16:07

Это не должно иметь значения. Смотрите >>> import signal >>> signal.SIGALRM возвращается <Signals.SIGALRM: 14>

han solo 08.04.2019 16:07

не могли бы вы просто вставить для меня снимок экрана с содержанием и выводом print(signal.SIGALRM). Потому что я действительно не понимаю, что происходит

han solo 08.04.2019 16:15

Это очень странно: все еще происходит сбой: signal.signal(signal.SIGALRM, обработчик)

falukky 08.04.2019 16:15
Ответ принят как подходящий

Следующий код должен работать для вашего случая. Во-первых, он порождает процесс и ждет тайм-аута, ожидая, он будет продолжать проверять вывод процесса. Затем, когда шаблон будет сопоставлен, он сломается, иначе будет возбуждено исключение.

import time
import subprocess
import re


proc = subprocess.Popen(['/tmp/test.sh'], stdout=subprocess.PIPE)

timeout = time.time() + 10 # adjust the timeout value here
target = ".*started on .*"

while True:
    if time.time() >= timeout:
        raise Exception("Server wasn't started")
    else:
        output = proc.stdout.readline()
        # read a line of input

        if output == '' and proc.poll() is not None:
            # process is not running anymore, 
            # proc.poll() will return None if process is still running
            raise Exception("Server process has stopped")
        else:
            line = output.decode().strip()
            if re.match(target, line):
                # if the pattern is matched, do something and break
                print("Server has started")
                break
            time.sleep(0.5)

Это файл bash, который я использовал для тестирования. Сохраните как /tmp/test.sh

#!/bin/bash

echo "TEST"
sleep 1
echo "server has started on 0.0.0.0"

Я пытаюсь изменить цель на что-то, что будет отсутствовать, и код не вызовет исключение

falukky 08.04.2019 16:28

@falukky, вы хотите вызвать исключение только тогда, когда истечет время ожидания, верно? Я думаю, что шаблон target, который вы используете, подходит. Можете ли вы сказать мне значение шаблона target и фактическую строку, которую вы пытаетесь сопоставить?

thuyein 08.04.2019 16:31

@falukky, вы можете просто попробовать закомментировать оператор эха в test.sh. Это вызовет исключение, поскольку шаблон target не может быть сопоставлен.

thuyein 08.04.2019 16:33

Другие вопросы по теме