【问题标题】:Python: get default gateway for a local interface/ip address in linuxPython:在 linux 中获取本地接口/IP 地址的默认网关
【发布时间】:2011-02-15 06:02:16
【问题描述】:

在 Linux 上,如何使用 python 找到本地 IP 地址/接口的默认网关?

我看到了“如何获取 UPnP 的内部 IP、外部 IP 和默认网关”的问题,但接受的解决方案只显示了如何在 windows 上获取网络接口的本地 IP 地址。

谢谢。

【问题讨论】:

  • 您可以使用python执行系统的'route'命令,然后处理输出以获得默认网关。也可能有一个用于仅打印该路线的标志。我不知道python方式atm。祝你好运。

标签: python linux routing networking


【解决方案1】:

对于那些不想要额外依赖并且不喜欢调用子进程的人,您可以通过直接阅读/proc/net/route 来自己做这件事:

import socket, struct

def get_default_gateway_linux():
    """Read the default gateway directly from /proc."""
    with open("/proc/net/route") as fh:
        for line in fh:
            fields = line.strip().split()
            if fields[1] != '00000000' or not int(fields[3], 16) & 2:
                # If not default route or not RTF_GATEWAY, skip it
                continue

            return socket.inet_ntoa(struct.pack("<L", int(fields[2], 16)))

我没有要测试的大端机器,所以我不确定字节顺序是否取决于您的处理器架构,但如果是,请将struct.pack('&lt;L', ... 中的&lt; 替换为@987654325 @ 所以代码将使用机器的本地字节序。

【讨论】:

    【解决方案2】:

    为了完整起见(并扩展 alastair 的答案),这是一个使用“netifaces”的示例(在 Ubuntu 10.04 下测试,但这应该是可移植的):

    $ sudo easy_install netifaces
    Python 2.6.5 (r265:79063, Oct  1 2012, 22:04:36)
    ...
    $ ipython
    ...
    In [8]: import netifaces
    In [9]: gws=netifaces.gateways()
    In [10]: gws
    Out[10]:
    {2: [('192.168.0.254', 'eth0', True)],
     'default': {2: ('192.168.0.254', 'eth0')}}
    In [11]: gws['default'][netifaces.AF_INET][0]
    Out[11]: '192.168.0.254'
    

    “netifaces”的文档:https://pypi.python.org/pypi/netifaces/

    【讨论】:

    • 在 Debian/Ubuntu 上由apt-get install python3-netifacesapt-get install python-netifaces 安装,如果您分别使用 Python 3 或 Python 2。
    【解决方案3】:

    看来http://pypi.python.org/pypi/pynetinfo/0.1.9可以做到这一点,但我没有测试过。

    【讨论】:

    • 那个图书馆很棒!它有一个 netinfo.get_routes 方法,该方法返回一个字典元组,其中包含我需要的数据。谢谢!
    【解决方案4】:

    netifaces 的最新版本也可以做到这一点,但与pynetinfo 不同的是,它可以在 Linux 以外的系统(包括 Windows、OS X、FreeBSD 和 Solaris)上运行。

    【讨论】:

      【解决方案5】:
      def get_ip():
          file=os.popen("ifconfig | grep 'addr:'")
          data=file.read()
          file.close()
          bits=data.strip().split('\n')
          addresses=[]
          for bit in bits:
              if bit.strip().startswith("inet "):
                  other_bits=bit.replace(':', ' ').strip().split(' ')
                  for obit in other_bits:
                      if (obit.count('.')==3):
                          if not obit.startswith("127."):
                              addresses.append(obit)
                          break
          return addresses
      

      【讨论】:

        【解决方案6】:

        你可以像这样得到它(用 python 2.7 和 Mac OS X Capitain 测试,但也应该在 GNU/Linux 上工作): 导入子流程

        def system_call(command):
            p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
            return p.stdout.read()
        
        
        def get_gateway_address():
            return system_call("route -n get default | grep 'gateway' | awk '{print $2}'")
        
        print get_gateway_address()
        

        【讨论】:

          【解决方案7】:

          这是我使用 python 获取 Mac 和 Linux 的默认网关的解决方案:

          import subprocess
          import re
          import platform
          
          def get_default_gateway_and_interface():
              if platform.system() == "Darwin":
                  route_default_result = subprocess.check_output(["route", "get", "default"])
                  gateway = re.search(r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", route_default_result).group(0)
                  default_interface = re.search(r"(?:interface:.)(.*)", route_default_result).group(1)
          
              elif platform.system() == "Linux":
                  route_default_result = re.findall(r"([\w.][\w.]*'?\w?)", subprocess.check_output(["ip", "route"]))
                  gateway = route_default_result[2]
                  default_interface = route_default_result[4]
          
              if route_default_result:
                  return(gateway, default_interface)
              else:
                  print("(x) Could not read default routes.")
          
          gateway, default_interface = get_default_gateway_and_interface()
          print(gateway)
          

          【讨论】:

            【解决方案8】:

            对于 Mac:

            import subprocess
            
            def get_default_gateway():
                route_default_result = str(subprocess.check_output(["route", "get", "default"]))
                start = 'gateway: '
                end = '\\n'
                if 'gateway' in route_default_result:
                    return (route_default_result.split(start))[1].split(end)[0]
            
            print(get_default_gateway())
            

            【讨论】:

              猜你喜欢
              • 2013-07-28
              • 1970-01-01
              • 2011-01-18
              • 2016-10-24
              • 2015-04-04
              • 2012-03-15
              • 1970-01-01
              • 2010-12-26
              • 1970-01-01
              相关资源
              最近更新 更多