2015-01-06 66 views
0

我有一个python脚本,我正在调用另一个使用子进程的脚本,如下所示。捕捉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") 

然后我需要知道这个信息。 simailar方式我们得到sys.exc_info()等

有没有办法我可以做到这一点?

由于提前

+0

除了下面的答案之外,有必要指出的是,Python可以直接调用其他python模块,而不需要子进程,这将允许您捕获异常。这是你在这种情况下应该做的。 – VooDooNOFX

回答

1

不,你不能从一个子进程得到sys.exc_info() - 通过你能看到的返回码,时间对象在内存中(包括堆栈跟踪)的子进程已经走了。

您可以通过为stderr输出提供一个单独的管道并读取该文件来解析您的子进程写入stderr的文本。假设你的程序不会写入标准错误,否则将在该流中显示的唯一文本将是错误消息和堆栈跟踪。

但是,您会希望对此方法持谨慎态度,因为如果进程将更多文本写入stderr而不是缓冲区,则会导致死锁。最好的解决方案是有一个单独的线程同时读取stdout和stderr。

0

如果你想得到sys.exc_info()那么你可以导入模块并运行它的功能,而不是使用subprocess模块。如果需要在不同的进程中运行,则可以使用multiprocessing模块。

另一种可能性是使用execfile()在与父脚本相同的过程中将模块作为脚本运行。如果您想将命令行参数传递给脚本,则可以在调用execfile()之前操作sys.argv全局列表。

或者你可以结合subprocess + execfile方法:编写使用execfile运行孩子脚本和序列化的所有异常包装脚本(例如,使用pickle)和父脚本中使用subprocess运行包装脚本。分别捕获stderr,以便能够解除孩子的异常信息。

+0

谢谢。唯一的问题是我需要运行带有参数的python文件,这个文件在execfile() – user2891472

+0

@ user2891472上看不到:我已经更新了答案,提到如何将命令行参数传递给使用'execfile( )' – jfs