简体   繁体   English

捕获python子进程异常

[英]Catching python subprocess exception

I have a python script where i am calling another script using subprocess as below. 我有一个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())

This is working fine for me but i want to get any exception from the script.py. 这对我来说工作正常,但我想从script.py中获取任何异常。 I know we can get the retcode but i actually need to get the full exception information. 我知道我们可以获取重新编码,但实际上我需要获取完整的异常信息。

If script.py raises 如果script.py引发

         raise IOERROR("got an exception")

then i need to know this information. 那么我需要知道这些信息。 simailar way we get the sys.exc_info() etc. simailar方法,我们得到sys.exc_info()等。

is there a way i can do this? 有办法可以做到吗?

Thanks in Advance 提前致谢

No, you can't get the sys.exc_info() from a subprocess -- by the time you're able to see the return code, objects in memory (including stack traces) of the child process are already gone. 不,您不能从子进程中获取sys.exc_info() -在您能够看到返回代码时,子进程的内存中对象(包括堆栈跟踪)已经消失了。

What you can do is parse the text your subprocess writes to stderr, by providing a separate pipe for the stderr output and reading that. 您可以做的是,通过为stderr输出提供单独的管道并读取该子进程,来解析子进程写入stderr的文本。 Assuming that your program never writes to stderr otherwise, the only text that will show up in that stream will be the error message and stack trace. 假设您的程序从未以其他方式写入stderr,则在该流中显示的唯一文本将是错误消息和堆栈跟踪。

You'll want to be cautious with this approach, though, because if the process writes more text to stderr than you can buffer, you'll deadlock. 但是,您将需要谨慎使用此方法,因为如果进程向stderr中写入的文本多于您可以缓冲的文本,则将导致死锁。 The best solution is to have a separate thread to read from both stdout and stderr in parallel. 最好的解决方案是让一个单独的线程从stdout和stderr中并行读取。

If you want to get sys.exc_info() then you could import the module and run functions from it instead of using subprocess module. 如果要获取sys.exc_info()则可以导入模块并从中运行功能,而不是使用subprocess模块。 You could use multiprocessing module if you need to run in a different process. 如果需要在其他进程中运行,则可以使用multiprocessing模块。

Another possibility is to use execfile() to run the module as a script in the same process as the parent script. 另一种可能性是在与父脚本相同的过程中使用execfile()作为脚本运行模块。 If you want to pass command-line arguments to the script then you could manipulate sys.argv global list before calling execfile() . 如果要将命令行参数传递给脚本,则可以在调用execfile()之前操作sys.argv全局列表。

Or you could combine subprocess + execfile methods: write a wrapper script that uses execfile to run the child script and serializes all exceptions (eg, using pickle ) and run the wrapper script using subprocess in your parent script. 或者,您可以结合使用subprocess + execfile方法:编写一个使用execfile运行子脚本并序列化所有异常的包装器脚本(例如,使用pickle ),并在父脚本中使用subprocess运行包装器脚本。 Capture stderr separately, to be able to unpickle child's exception info. 分别捕获stderr,以便能够获取孩子的异常信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM