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

Python subprocess error management. Not able to catch non-zero exit status

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

看这里我使用的代码:

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

有时我的加密狗可能会弹出并给出错误的性质:"This device does not have any GSM capabilities..."

我完全可以接受,因为它只需要简单的重试,它通常会工作得很好。

但是使用子进程我 运行 进入错误 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: 以尽可能广泛的方式捕获异常,即使这样做了,错误仍然存​​在并使软件崩溃。

我在尝试正确捕获此错误时不知所措,谁能告诉我这里到底发生了什么,因为此时(对我而言)似乎很难捕获由子进程引起的错误.

在此处查看我打算使用的完整功能:

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.'

我认为您做的是正确的...但是将引发异常的代码移到 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.'

此外,只是打印出错误,可能会帮助你调试代码:

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