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

0 投票
3 回答
2483 浏览
提问于 2025-04-30 02:41

我想要自动执行一个脚本,所以我使用了 subprocess 库来创建一个线程,并用 schedule 库来安排它的执行。

我想确认远程执行的脚本是否正常工作。可是我尝试的代码在脚本返回 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 个回答

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:
    ... 
-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() 会等这个程序运行完,然后返回一个结果代码(表示成功或失败)。同时,它还会实时显示输出内容。

撰写回答