我如何获得Python中的eth0的IP地址?

当Unix上的Python脚本发生错误时,会发送一封电子邮件。

如果IP地址是testing服务器的IP地址是192.168.100.37,我被要求添加{testing环境}到邮件的主题行。 这样,我们就可以拥有一个脚本版本,并且可以通过这种方式来判断电子邮件是否来自testing服务器上的混乱数据。

但是,当我谷歌我不断find这个代码:

import socket socket.gethostbyname(socket.gethostname()) 

但是,这是给我的IP地址127.0.1.1。 当我使用ifconfig我得到这个

 eth0 Link encap:Ethernet HWaddr 00:1c:c4:2c:c8:3e inet addr:192.168.100.37 Bcast:192.168.100.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:75760697 errors:0 dropped:411180 overruns:0 frame:0 TX packets:23166399 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:59525958247 (59.5 GB) TX bytes:10142130096 (10.1 GB) Interrupt:19 Memory:f0500000-f0520000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:25573544 errors:0 dropped:0 overruns:0 frame:0 TX packets:25573544 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:44531490070 (44.5 GB) TX bytes:44531490070 (44.5 GB) 

首先,我不知道它从哪里得到127.0.1.1,但是这不是我想要的。 当我谷歌我不断来到相同的语法, Bash脚本或netifaces,我试图使用标准库。

那么我怎样才能在Python中得到eth0的IP地址呢?

两种方法:

方法#1(使用外部包)

您需要询问绑定到您的eth0接口的IP地址。 这可以从netifaces包中获得

 import netifaces as ni ni.ifaddresses('eth0') ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr'] print ip # should print "192.168.100.37" 

您也可以通过获取所有可用接口的列表

 ni.interfaces() 

方法#2(没有外部包装)

这里有一个获取IP地址而不使用python包的方法:

 import socket import fcntl import struct def get_ip_address(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15]) )[20:24]) get_ip_address('eth0') # '192.168.0.110' 

注意:检测IP地址,以确定您使用的是什么环境是相当黑客。 几乎所有的框架都提供了一个非常简单的方法来设置/修改一个环境variables来表示当前的环境。 试着看看你的文档。 它应该像做一样简单

 if app.config['ENV'] == 'production': #send production email else: #send development email 

或者,如果您想获取用于连接到networking的接口的IP地址,而无需知道其名称,则可以使用以下命令:

 import socket def get_ip_address(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) return s.getsockname()[0] 

我知道这与你的问题有点不同,但其他人可能会到达这里,发现这个更有用。 你不必有一个到8.8.8.8的路线来使用它。 它所做的只是打开一个套接字,但不发送任何数据。

如果你只需要在Unix上工作,你可以使用系统调用(参考Stack Overflow的问题parsingifconfig来获取我的IP地址使用Bash ):

 import os f = os.popen('ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1') your_ip=f.read() 

返回接口的IP地址string的简单方法是:

 from subprocess import check_output ips = check_output(['hostname', '--all-ip-addresses']) 

有关更多信息,请参阅主机名 。

由于大多数答案使用ifconfig从eth0接口提取IPv4,而不赞成使用ip addr ,因此可以使用以下代码:

 import os ipv4 = os.popen('ip addr show eth0 | grep "\<inet\>" | awk \'{ print $2 }\' | awk -F "/" \'{ print $1 }\'').read().strip() ipv6 = os.popen('ip addr show eth0 | grep "\<inet6\>" | awk \'{ print $2 }\' | awk -F "/" \'{ print $1 }\'').read().strip() 

更新:

或者,您可以使用split()而不是grep和awk将parsing任务的一部分移至python解释器,正如@serg在注释中指出的那样:

 import os ipv4 = os.popen('ip addr show eth0').read().split("inet ")[1].split("/")[0] ipv6 = os.popen('ip addr show eth0').read().split("inet6 ")[1].split("/")[0] 

但在这种情况下,你必须检查每个split()调用返回的数组边界。

更新2:

使用正则expression式的另一个版本:

 import os import re ipv4 = re.search(re.compile(r'(?<=inet )(.*)(?=\/)', re.M), os.popen('ip addr show eth0').read()).groups()[0] ipv6 = re.search(re.compile(r'(?<=inet6 )(.*)(?=\/)', re.M), os.popen('ip addr show eth0').read()).groups()[0] 

尝试下面的代码,它适用于Mac10.10.2中的我:

 import subprocess if __name__ == "__main__": result = subprocess.check_output('ifconfig en0 |grep -w inet', shell=True) # you may need to use eth0 instead of en0 here!!! print 'output = %s' % result.strip() # result = None ip = '' if result: strs = result.split('\n') for line in strs: # remove \t, space... line = line.strip() if line.startswith('inet '): a = line.find(' ') ipStart = a+1 ipEnd = line.find(' ', ipStart) if a != -1 and ipEnd != -1: ip = line[ipStart:ipEnd] break print 'ip = %s' % ip 

它为我工作

  import subprocess my_ip = subprocess.Popen(['ifconfig eth0 | awk "/inet /" | cut -d":" -f 2 | cut -d" " -f1'], stdout=subprocess.PIPE, shell=True) (IP,errors) = my_ip.communicate() my_ip.stdout.close() print IP 

在正在运行的ifconfig中查找第一个eth / wlan条目的IP地址:

 import itertools import os import re def get_ip(): f = os.popen('ifconfig') for iface in [' '.join(i) for i in iter(lambda: list(itertools.takewhile(lambda l: not l.isspace(),f)), [])]: if re.findall('^(eth|wlan)[0-9]',iface) and re.findall('RUNNING',iface): ip = re.findall('(?<=inet\saddr:)[0-9\.]+',iface) if ip: return ip[0] return False