python捕获异常

时间:2012-03-26 11:31:53

标签: python linux

我正在运行curl命令来检查网站的状态:

try:
    connectionTest = subprocess.Popen([r"curl --interface xx.xx.xx.xx http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e

除了try:except语句之外,代码工作正常,因为它没有正确捕获异常,下面是接口关闭时脚本的输出,现在我想在except语句中捕获第一行。而不是产生......这可能吗?

SIOCSIFFLAGS: Cannot assign requested address

PROBLEM

3 个答案:

答案 0 :(得分:5)

没有抛出异常。 您可以检查返回代码并在非零时抛出异常:

import sys, subprocess
try:
    connectionTest = subprocess.Popen([r"curl --interface 1.1.1.1 http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if connectionTest.returncode:
        raise Exception("Curl returned %s"%connectionTest.returncode)
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e

答案 1 :(得分:3)

如果子进程中发生任何异常,则不会抛出它。 检查stderr并引发适当的异常

try:
    connectionTest = subprocess.Popen([r"curl --interface xx.xx.xx.xx http://www.yahoo.com"], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    cstdout,cstderr = connectionTest.communicate()
    if cstdout:
        #print cstdout
        status = "OK"
    elif cstderr:
        #print cstderr
        status = "PROBLEM"
        raise some exception
except:
    e = sys.exc_info()[1]
    print "Error: %s" % e

答案 2 :(得分:0)

你确定需要打电话来卷曲吗?

import urllib2
try:
    urllib2.urlopen("http://www.yahoo.com")
except urllib2.URLError as err:
    print(err)
except urllib2.HTTPError as err:
    print(err)

其次,听起来你的界面地址很狡猾,而不是你的代码。检查--interface标志参数的正确性(即:在python之外运行curl命令并检查它是否按预期工作。

总的来说,你永远无法在python程序中捕获子进程错误(我认为你在问这个问题)。您必须依赖退出代码 stdout / err输出,这就是依赖于Python included batteries的解决方案将更加强大的原因。

如果您需要手动指定界面,还有其他几个选项:

  1. PyCurl

    import pycurl
    import StringIO
    c = pycurl.Curl()
    c.setopt(pycurl.URL, "http://www.python.org/")
    c.setopt(pycurl.CURLOPT_INTERFACE, "eth0")
    # [...]
    try:
        c.perform()
    except: # Handle errors here.
      pass 
    
  2. Change the source interface manually in python for urllib2