我正在使用python 2.7并尝试检查执行的前10秒内的stderr是否返回任何错误,如果没有,继续该过程,我不是在等待该过程结束,因为它是一个循环。
我收到了这段代码:
p = subprocess.Popen(
["python", os.getcwd() + "/start.py", 1hr, 30min, 0, 0],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if len(p.stderr.readlines()) is not None:
print p.stderr.readlines()
return jsonify(status="failed",
error_details=p.stderr.readlines()
)
问题是,在读完stderr的长度之后,stderr会自行清除,因此我无法检查值并发布消息,因此print p.stderr.readlines()
变为空列表。
{
"error_details": [],
"status": "failed"
}
我不想显示输出,我只想运行start.py
并检查错误,如果10秒左右没有出现错误,则表示一切顺利,可以继续运行循环由子进程在后台启动而不检查它。我可以以某种方式继续,如果p
进程在1小时左右后仍然无法返回错误,执行回调?我可以以某种方式存储stderr来回复消息吗?另外,你如何建议我在10秒内制作一个计数器来检查是否弹出错误?即使文件不存在,使用p.pool()
也不会返回任何错误代码。
答案 0 :(得分:2)
当然,您可以存储readlines
的结果,这样您就不会使用缓冲区,但您的代码存在更严重的问题。
对subprocess.PIPE
和stdout
使用stderr
并在此之后尝试阅读stderr
会导致死锁。
此外,在某些情况下,进程可以无声地失败,并且stderr
中没有写入任何内容。这不是获取返回代码的正确方法。
执行此操作的唯一(更简单方法)是使用communicate
:
p = subprocess.Popen(
["python", os.getcwd() + "/start.py", "1hr", "30min", "0", "0"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = p.communicate()
rc = p.wait()
if rc: # non-zero return code
return jsonify(status="failed",
error_details=err.decode().splitlines())
你得到输出&透明地读取2个单独的线程中的错误(不可能出现死锁),并测试返回代码。如果不为零,则发生错误。拆分解码器错误输出(python 3)的行并返回错误。
请注意,splitlines()
会删除行终止(而不是流上的readlines()
。
上述方法无法处理"等待10秒然后测试错误输出"做法。这可以:
p = subprocess.Popen(
["python", os.getcwd() + "/start.py", "1hr", "30min", "0", "0"],
stdout=subprocess.DEVNULL, # don't read stdout, avoids deadlock
# stdout=devnull, # python 2, where devnull = open(os.devnull, 'w')
stderr=subprocess.PIPE)
# now wait 10 seconds
time.sleep(10)
if p.poll() is not None and p.poll() != 0:
return jsonify(status="failed",
error_details=p.stderr.readlines() # add .decode() for python 3
)
上述方法等待10秒,然后测试进程是否以错误结束,返回错误/读取错误输出。