我如何获得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