我正在寻找一个命令行解决方案,将返回我的主(第一个)IP地址的本地主机,而不是127.0.0.1
该解决方案至少适用于Linux (Debian和RedHat)和OS X 10.7+
我知道在这两个平台上都可以使用ifconfig,但是它的输出在这些平台之间并不一致。
我正在寻找一个命令行解决方案,将返回我的主(第一个)IP地址的本地主机,而不是127.0.0.1
该解决方案至少适用于Linux (Debian和RedHat)和OS X 10.7+
我知道在这两个平台上都可以使用ifconfig,但是它的输出在这些平台之间并不一致。
当前回答
编辑(2014-06-01 2018-01-09 2021-07-25)
从一段时间前,我现在使用更新的ip工具。但在bash下,我会简单地做:
read -r _{,} gateway _ iface _ ip _ < <(ip r g 1.0.0.0)
Then
printf '%-12s %s\n' gateway $gateway iface $iface ip $ip
gateway 192.168.1.1
iface eth0
ip 192.168.1.37
从那里,蒙版是:
while IFS=$' /\t\r\n' read lne lip lmask _;do
[ "$lne" = "inet" ] && [ "$lip" = "$ip" ] && mask=$lmask
done < <(ip a s dev $iface)
echo Mask is $mask bits.
Mask is 24 bits.
然后如果你想把你的掩码作为一个IP:
printf -v msk '%*s' $mask ''
printf -v msk %-32s ${msk// /1}
echo $((msk=2#${msk// /0},msk>>24)).$((msk>>16&255)).$((msk>>8&255)).$((msk&255))
255.255.255.0
编辑(2014-06-01 2018-01-09)
为了更强的配置,在每个接口上配置了许多接口和许多IP,我编写了一个纯bash脚本(不是基于127.0.0.1),用于根据默认路由查找正确的接口和IP。我把这个脚本贴在这个答案的最下面。
介绍
因为两个操作系统都默认安装了bash,所以Mac和Linux都有一个bash提示:
使用LANG=C可以避免区域问题:
myip=
while IFS=$': \t' read -a line ;do
[ -z "${line%inet}" ] && ip=${line[${#line[1]}>4?1:2]} &&
[ "${ip#127.0.0.1}" ] && myip=$ip
done< <(LANG=C /sbin/ifconfig)
echo $myip
把这些放到一个函数中:
最小:
getMyIP() {
local _ip _line
while IFS=$': \t' read -a _line ;do
[ -z "${_line%inet}" ] &&
_ip=${_line[${#_line[1]}>4?1:2]} &&
[ "${_ip#127.0.0.1}" ] && echo $_ip && return 0
done< <(LANG=C /sbin/ifconfig)
}
简单的使用:
getMyIP
192.168.1.37
喜欢整洁:
getMyIP() {
local _ip _myip _line _nl=$'\n'
while IFS=$': \t' read -a _line ;do
[ -z "${_line%inet}" ] &&
_ip=${_line[${#_line[1]}>4?1:2]} &&
[ "${_ip#127.0.0.1}" ] && _myip=$_ip
done< <(LANG=C /sbin/ifconfig)
printf ${1+-v} $1 "%s${_nl:0:$[${#1}>0?0:1]}" $_myip
}
用法:
getMyIP
192.168.1.37
或者,运行相同的函数,但带有参数:
getMyIP varHostIP
echo $varHostIP
192.168.1.37
set | grep ^varHostIP
varHostIP=192.168.1.37
注意:没有参数,这个函数输出在STDOUT, IP和一个换行符,有一个参数,什么都不打印,但是一个名为参数的变量被创建,包含IP没有换行符。
Nota2:这是在Debian, LaCie黑nas和MaxOs上测试的。如果这在你的环境下行不通,我将非常感兴趣的反馈!
这个答案的旧版本
(没有删除,因为基于sed,而不是bash。)
警告:有一个关于区域设置的问题!
又快又小:
myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}')
爆炸(工作也是;)
myIP=$(
ip a s |
sed -ne '
/127.0.0.1/!{
s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p
}
'
)
编辑:
如何!这似乎不工作在Mac OS…
好吧,这似乎在Mac OS和我的Linux上是一样的:
myIP=$(LANG=C /sbin/ifconfig | sed -ne $'/127.0.0.1/ ! { s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p; }')
splitted:
myIP=$(
LANG=C /sbin/ifconfig |
sed -ne $'/127.0.0.1/ ! {
s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p;
}')
我的剧本(2018年1月):
此脚本将首先找到用于的默认路由和接口,然后搜索网关的本地ip匹配网络并填充变量。最后两行输出,如下所示:
Interface : en0
Local Ip : 10.2.5.3
Gateway : 10.2.4.204
Net mask : 255.255.252.0
Run on mac : true
or
Interface : eth2
Local Ip : 192.168.1.31
Gateway : 192.168.1.1
Net mask : 255.255.255.0
Run on mac : false
好吧,就是这样:
#!/bin/bash
runOnMac=false
int2ip() { printf ${2+-v} $2 "%d.%d.%d.%d" \
$(($1>>24)) $(($1>>16&255)) $(($1>>8&255)) $(($1&255)) ;}
ip2int() { local _a=(${1//./ }) ; printf ${2+-v} $2 "%u" $(( _a<<24 |
${_a[1]} << 16 | ${_a[2]} << 8 | ${_a[3]} )) ;}
while IFS=$' :\t\r\n' read a b c d; do
[ "$a" = "usage" ] && [ "$b" = "route" ] && runOnMac=true
if $runOnMac ;then
case $a in
gateway ) gWay=$b ;;
interface ) iFace=$b ;;
esac
else
[ "$a" = "0.0.0.0" ] && [ "$c" = "$a" ] && iFace=${d##* } gWay=$b
fi
done < <(/sbin/route -n 2>&1 || /sbin/route -n get 0.0.0.0/0)
ip2int $gWay gw
while read lhs rhs; do
[ "$lhs" ] && {
[ -z "${lhs#*:}" ] && iface=${lhs%:}
[ "$lhs" = "inet" ] && [ "$iface" = "$iFace" ] && {
mask=${rhs#*netmask }
mask=${mask%% *}
[ "$mask" ] && [ -z "${mask%0x*}" ] &&
printf -v mask %u $mask ||
ip2int $mask mask
ip2int ${rhs%% *} ip
(( ( ip & mask ) == ( gw & mask ) )) &&
int2ip $ip myIp && int2ip $mask netMask
}
}
done < <(/sbin/ifconfig)
printf "%-12s: %s\n" Interface $iFace Local\ Ip $myIp \
Gateway $gWay Net\ mask $netMask Run\ on\ mac $runOnMac
其他回答
如果你知道网络接口(eth0, wlan, tun0等):
ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2
下面的代码可以在Linux上运行,但不能在OSX上运行。
这根本不依赖于DNS,即使/etc/hosts没有正确设置(1是1.0.0.0的简写),它也能工作:
ip route get 1 | awk '{print $NF;exit}'
或者避免awk,使用谷歌的公共DNS 8.8.8.8。
ip route get 8.8.8.8 | head -1 | cut -d' ' -f8
一种不太可靠的方式:(见下面的评论)
hostname -I | cut -d' ' -f1
对于linux,你需要的是这个命令:
ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'
在你的shell中输入这个,你就会知道你的ip。
使用其他方法您可能会输入系统上定义了多个IP地址的冲突。 这一行总是获得默认使用的IP地址。
ip route get 8.8.8.8 | head -1 | awk '{print $7}'
在一个默认网关的网络中查找这台计算机的IP地址(例如排除所有虚拟网络,docker桥接器)。互联网网关,wifi网关,以太网
ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
适用于Linux。
测试:
➜ ~ ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
192.168.0.114
➜ reverse-networking git:(feature/type-local) ✗ ifconfig wlp2s0
wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.114 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::d3b9:8e6e:caee:444 prefixlen 64 scopeid 0x20<link>
ether ac:x:y:z txqueuelen 1000 (Ethernet)
RX packets 25883684 bytes 27620415278 (25.7 GiB)
RX errors 0 dropped 27 overruns 0 frame 0
TX packets 7511319 bytes 1077539831 (1.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0