Python子进程错误管理。无法捕获非零退出状态

时间:2016-04-02 12:37:55

标签: python linux python-2.7 subprocess

我正在使用python中的子进程模块使用sakis3g将我的3G加密狗连接到3G网络。

请参阅此处使用的代码:

check_output(['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"'])

有时我的加密狗可能会输出并出现以下错误:“此设备没有任何GSM功能......”

我可以完全忍受,因为它需要的只是一个简单的重试,它通常会正常工作。

但是使用子进程时我遇到了错误returned non-zero exit status,它会彻底崩溃我的软件。

由于我只需要重试,我尝试使用try: ... except: ...进行编码。 我试图捕获的错误是subprocess.CalledProcessError,如果根据the documentation退出状态为非零,则应由check_output返回。

然而,这似乎没有解决问题,问题仍然存在:

Traceback (most recent call last):
  File "run.py", line 91, in <module>
    print connect_3G()
  File "run.py", line 28, in connect_3G
    check_call(['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"'])
  File "/usr/lib/python2.7/subprocess.py", line 540, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"']' returned non-zero exit status 95

所以我试图通过简单地使用except:以最广泛的方式捕获异常,即使完成此操作,错误仍然会通过并崩溃软件。

我无法正确地捕捉到这个错误,是否有人能够告诉我这里究竟发生了什么,因为在这一点上看起来很难找到由子进程引起的错误(对我而言)。 / p>

请参阅我在此处使用的完整功能:

def connect_3G():
    while True:
        check_output(['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"'])
        try:
            return 'Connected to ip: {}'.format(json.loads(requests.get('http://httpbin.org/ip').content)['origin'])
        except subprocess.CalledProcessError:
            print 'Oops, problem connecting to 3G. Better retry fam.'

2 个答案:

答案 0 :(得分:2)

此外,只需打印出错误,可以帮助您调试代码:

def connect_3G():
    while True:
        try:
            check_output(['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"'])
            return 'Connected to ip: {}'.format(json.loads(requests.get('http://httpbin.org/ip').content)['origin'])
        except subprocess.CalledProcessError as error:
            print 'Oops, problem connecting to 3G. Better retry fam.', error.message

答案 1 :(得分:1)

我认为你做的是正确的事情......但是移动了将异常抛到try区块内的代码!

def connect_3G():
    while True:
        try:
            check_output(['sakis3g', '--sudo', 'connect', 'OTHER="USBMODEM"', 'USBMODEM="12d1:1001"', 'APN="internet"'])
            return 'Connected to ip: {}'.format(json.loads(requests.get('http://httpbin.org/ip').content)['origin'])
        except subprocess.CalledProcessError:
            print 'Oops, problem connecting to 3G. Better retry fam.'