在服务器上可能有多个networking接口,例如lo,eth0,eth1
从路由表中,我知道eth0连接到默认网关。 默认网关的地址,例如,是192.168.1.1。 eth0的地址是192.168.1.100。
我怎样才能得到地址“192.168.1.100”? 任何方法都可以:Python,Shell,UNIX C API …
目前我只能想到一种方法:
有更好的解决scheme吗?
PS:有人build议我们可以在udp socket上调用connect(),然后调用getsockname()来得到本地地址。 但是,它只适用于部分服务器。
@EEAA
所以这是我的脚本:
route -n | awk '$1 == "0.0.0.0" { print $2 }' > gateway.tmp ip -4 addr show | grep inet | awk '{ print $2 }' > addrs.tmp
第一行打印默认网关:
10.1.40.1
第二行打印接口地址列表(以cidr表示法):
127.0.0.1/8 10.1.46.122/21
然后我必须决定哪个networking10.1.40.1属于。 所以我写了一个Python脚本:
import sys def ip_to_binary(ip): bytes = ip.split(".") a = int(bytes[0]) b = int(bytes[1]) c = int(bytes[2]) d = int(bytes[3]) return "{0:08b}{1:08b}{2:08b}{3:08b}".format(a, b, c, d) def mask_to_binary(bits): return "1" * bits + "0" * (32 - bits) def binary_and(a, b): if len(a) == len(b): result = "" for i in range(0, len(a)): if a[i] == "1" and b[i] == "1": result += "1" else: result += "0" return result return None def ip_in_net(ip, net_cidr_notation): net_addr, bits = net_cidr_notation.split("/") bin_mask = mask_to_binary(int(bits)) bin_net = ip_to_binary(net_addr) bin_ip = ip_to_binary(ip) if binary_and(bin_ip, bin_mask) == binary_and(bin_net, bin_mask): return True return False # usage: python autoaddr.py gateway_file addrs_file gateway = open(sys.argv[1]).readline().strip() addrs = open(sys.argv[2]).readlines() for addr in addrs: if ip_in_net(gateway, addr): print addr.split("/")[0]
为了避免额外的依赖,我没有使用像netaddr和ipaddress这样的库。 最后,我必须将Python脚本添加到Shell脚本中:
python autoaddr.py gateway.tmp addrs.tmp > auto.tmp rm -f gateway.tmp rm -f addrs.tmp
现在我有一个文件auto.tmp包含自动生成的地址:
10.1.46.122
为什么不是这样的:
$ ip -4 addr show eth0 | grep inet | awk '{ print $2 }' 192.168.1.100/24
仅供参考, ifconfig
已弃用。 你应该开始使用各种ip
命令来代替之前使用ifconfig
地方。