捕获另一个函数调用的子进程的异常

时间:2014-10-28 08:06:32

标签: python exception subprocess wrapper

我想在子进程上自动执行脚本,所以我使用subprocess lib来创建线程,并使用schedule lib来安排它。

我想验证远程执行的脚本是否正常运行。 当脚本返回1(错误)或script_file不存在时,我尝试的代码不会打印任何错误。 (如果我没弄错的话,添加异常包装器可以杀死子进程并完成它的工作)

import os
import sys
import subprocess
import multiprocessing
import schedule
import time
import functools

class MyClass:

        def catch_exceptions(job_func):
                @functools.wraps(job_func)
                def wrapper(*args, **kwargs):
                        try:
                                job_func(*args, **kwargs)
                        except:
                                import traceback
                                print ("Error")
                                print(traceback.format_exc())
                return wrapper


        @catch_exceptions
        def run(self, user, host, command):
                subprocess.call(["ssh", user + "@" + host, command])


        def sched(user, host, script_path):          
               schedule.every(0.01).minutes.do(self.run, user, host, script_path)

欢迎所有建议,使用包装器不是目标,但验证sched方法执行的任何解决方案都是好的。

3 个答案:

答案 0 :(得分:3)

call返回进程的退出代码。所以你可以检查一下。或者尝试subprocess.check_call。当进程以非零值退出时,它会抛出异常,因此您不必显式检查退出值,并捕获要处理它的异常。

示例:

exit_value = subprocess.call(cmd) 
if exit_value:
    ... 

try:
    subprocess.check_call(cmd) 
except CalledProcessError as e:
    ... 

答案 1 :(得分:1)

x=subprocess.Popen(["ssh", user + "@" + host, command],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output,error=x.communicate()
if error:
    print "there's an error!!!!!!!!!!!!!!:",error

您可以尝试这样做。subprocess.communicate如果成功则返回output,如果命令失败则返回error

答案 2 :(得分:-1)

使用subprocess.Popen()

RunCmd = Popen( sCmd, shell=True, stdout=PIPE, stderr=PIPE)

for sLine in RunCmd.stdout:
            print( sLine.decode() )
            stdout.flush()
            aLog.append( sLine.decode() )
for sLine in RunCmd.stderr:
            print( sLine.decode() )
            stderr.flush()
            aErrorLog.append( sLine.decode() )
RunCmd.wait()
if RunCmd.returncode == 0:
            return RunCmd.wait()
        else: 
            return RunCmd.returncode

RunCmd.wait()将等待进程完成,并将返回进程代码(for succuss或failure) 这也会实时打印输出。