[英]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.