Python: запустите bach-файл и читайте вывод до появления конкретной строки и продолжайте - PullRequest
2 голосов
/ 08 апреля 2019

Итак, у меня есть 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 secods прошло и эта строка (Appium REST http interface listener started on 0.0.0.0:4723) не появилась, я хочу поднять exception.

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

Есть предложения, как его решить?

Ответы [ 3 ]

1 голос
/ 08 апреля 2019

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

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"
1 голос
/ 08 апреля 2019

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

import time

time.sleep(60) # wait for 60 seconds
0 голосов
/ 08 апреля 2019

Вы можете сделать это с 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...")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...