我有一个python脚本,我正在使用子进程调用另一个脚本,如下所示。
sp = subprocess.Popen("script.py --arg1 --arg2', cwd=GIVEN_PATH, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while sp.poll() is None:
for out in iter(sp.stdout.readline,''):
self.log(out.rstrip())
这对我来说工作正常,但我想从 script.py 中获得任何例外。我知道我们可以获得 retcode,但我实际上需要获得完整的异常信息。
如果 script.py 提高
raise IOERROR("got an exception")
然后我需要知道这些信息。 我们得到sys.exc_info()等的simailar方式。
有没有办法做到这一点?
提前致谢
不,您无法从子进程中获取sys.exc_info()
- 当您能够看到返回代码时,子进程的内存中的对象(包括堆栈跟踪)已经消失。
您可以做的是解析子进程写入 stderr 的文本,方法是为 stderr 输出提供单独的管道并读取该管道。假设您的程序从不写入 stderr,否则该流中显示的唯一文本将是错误消息和堆栈跟踪。
但是,您需要谨慎使用此方法,因为如果进程向 stderr 写入的文本多于您可以缓冲的文本,则会死锁。最好的解决方案是有一个单独的线程来并行读取 stdout 和 stderr。
得到sys.exc_info()
那么你可以导入模块并从中运行函数,而不是使用subprocess
模块。如果需要在不同的进程中运行multiprocessing
可以使用该模块。
另一种可能性是使用 execfile()
在与父脚本相同的进程中将模块作为脚本运行。如果要将命令行参数传递给脚本,则可以在调用execfile()
之前操作sys.argv
全局列表。
或者你可以结合subprocess
+ execfile
方法:编写一个包装器脚本,该脚本使用 execfile
运行子脚本并序列化所有异常(例如,使用 pickle
),并在父脚本中使用 subprocess
运行包装器脚本。单独捕获标准,以便能够解冻孩子的异常信息。