Python: obtenga la puerta de enlace predeterminada para una interfaz local / dirección IP en Linux

En Linux, ¿cómo puedo encontrar la puerta de enlace predeterminada para una dirección IP / interfaz local usando python?

Vi la pregunta “Cómo obtener una IP interna, una IP externa y una puerta de enlace predeterminada para UPnP”, pero la solución aceptada solo muestra cómo obtener la dirección IP local para una interfaz de red en Windows.

Gracias.

Para aquellas personas que no quieren una dependencia adicional y no les gusta llamar a los subprocesos, a continuación le indicamos cómo hacerlo usted mismo leyendo /proc/net/route directamente:

 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: continue return socket.inet_ntoa(struct.pack(" 

No tengo una máquina big-endian para probar, así que no estoy seguro de si el endianness depende de la architecture de su procesador, pero si lo está, reemplace el < in struct.pack(' .con = por lo que el código utilizará la endianness nativa de la máquina.

Para completar (y para ampliar la respuesta de alastair), aquí hay un ejemplo que usa “netifaces” (probado bajo Ubuntu 10.04, pero esto debería ser portátil):

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

Documentación para ‘netifaces’: https://pypi.python.org/pypi/netifaces/

Parece que http://pypi.python.org/pypi/pynetinfo/0.1.9 puede hacer esto, pero no lo he probado.

La última versión de netifaces puede hacer esto, pero a diferencia de pynetinfo , funcionará en sistemas distintos de Linux (incluidos Windows, OS X, FreeBSD y Solaris).

 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 

Puede obtenerlo de esta forma (probado con Python 2.7 y Mac OS X Capitain, pero también debería funcionar en GNU / Linux): subproceso de importación

 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() 

Aquí mi solución para obtener la puerta de enlace predeterminada para Mac y Linux con Python:

 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)