Python子进程 - stderr在读取后擦除
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python子进程 - stderr在读取后擦除相关的知识,希望对你有一定的参考价值。
我正在使用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()
也不会返回任何错误代码。
当然你可以存储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秒,然后测试进程是否以错误结束,返回错误/读取错误输出。
以上是关于Python子进程 - stderr在读取后擦除的主要内容,如果未能解决你的问题,请参考以下文章
在 Docker 上运行的 Mongodb 正在重新启动后擦除集合