#python #subprocess
#python #подпроцесс
Вопрос:
Итак, у меня есть 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
процесс.
Есть предложения, как это решить?
Ответ №1:
Следующий код должен работать для вашего случая. Сначала он запускает процесс и ожидает тайм-аута, во время ожидания он будет продолжать проверять выходные данные процесса. Затем, когда шаблон будет сопоставлен, он будет прерван, иначе будет вызвано исключение.
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. Я пытаюсь изменить цель на то, что будет отсутствовать, и код не вызывает исключения
2. @falukky вы хотите вызывать исключение только по истечении времени ожидания, верно? Я думаю
target
, что шаблон, который вы используете, соответствует. Можете ли вы сказать мне значениеtarget
шаблона и фактическую строку, которую вы пытаетесь сопоставить?3. @falukky вы можете просто попробовать прокомментировать оператор echo в
test.sh
. Это вызовет исключение, посколькуtarget
шаблон не может быть сопоставлен
Ответ №2:
Вы можете подождать, используя модуль time
import time
time.sleep(60) # wait for 60 seconds
Комментарии:
1. Но как я могу выйти, когда получу нужную строку? я не могу убить процесс appium, потому что я хочу его использовать
Ответ №3:
Вы могли бы сделать это с помощью 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...")
Комментарии:
1. Я немного смущен, где именно мне нужно использовать этот код и как?
2. @falukky Я предполагаю
.communicate()
, что он будет блокироваться до техREST API
пор, пока не появится?3. В настоящее время мой код печатает выходные данные процесса, и поскольку процесс, выполняющий его, никогда не продолжается, и вы завершаете работу в этой строке: signal.signal(сигнал. SIGALRM, обработчик)
4. О чем это говорит
crash
?5. Ошибка атрибута: модуль ‘signal’ не имеет атрибута ‘SIGALRM’