2014-10-28 63 views
0

我想在一个子进程上自动执行一个脚本,所以我使用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方法也好。

回答

-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()将等待进程结束,并将返回的过程代码(succuss或失败) 这也打印输出在实时。

+0

如果stdout和标准错误都被重定向,那么你应该阅读他们两个同时否则程序可能会永远挂起。另外,OP不重定向远程子进程的输出。 – jfs 2014-10-28 17:29:02

+0

供参考:http://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29 “流是独立的,可以单独重定向”。我从来没有面对过这个代码的任何问题。 – Niyojan 2014-10-29 03:55:30

+0

这只是表示在所有情况下输出都很小。想象一下,当'sCmd'输出的内容(累积地)大于操作系统管道缓冲区时,会发生什么情况:当父进程试图从标准输出写入标准错误但它的标准错误管道缓冲区已满时, 。在子流程文档中有关于它的警告。 – jfs 2014-10-29 07:11:51

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如果命令失败。

3

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

例子:

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

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