Python:启动批处理文件并读取输出,直到显示特定行并继续

问题描述 投票:2回答:3

所以我有启动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进程。

有什么建议怎么解决?

python subprocess
3个回答
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
投票

您可以使用时间模块等待

import time

time.sleep(60) # wait for 60 seconds

0
投票

你可以用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...")
© www.soinside.com 2019 - 2024. All rights reserved.