我正在寻找一个命令行解决方案,将返回我的主(第一个)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,但是它的输出在这些平台之间并不一致。
当前回答
主网口IP
ifconfig `ip route | grep default | head -1 | sed 's/\(.*dev \)\([a-z0-9]*\)\(.*\)/\2/g'` | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1
其他回答
解决方案
$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'
192.168.8.16
解释
查询网络信息的正确方法是使用ip:
-o单行输出 Route get获取到目的地的实际内核路由 8.8.8.8谷歌IP,但可以使用您想要到达的真实IP
例如IP输出:
8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \ cache
要提取src ip, sed是最轻的,最兼容regex支持:
-n默认不输出 's/pattern/replacement/p'只匹配模式和打印替换 . * src \([0 - 9] \ + \)。*匹配内核使用的src IP,达到8.8.8.8
例如,最终输出:
192.168.8.16
其他答案
我认为前面的答案对我来说都不够好,因为它们在最近的机器上不起作用(Gentoo 2018)。
我在前面的答案中发现的问题:
在命令输出中使用位置列; 使用已弃用的ifconfig,例如,不要列出多个ip; 使用awk来完成简单的任务,而sed可以更好地处理这些任务; IP route get 1不清楚,实际上是IP route get到1.0.0.0的别名 使用hostname命令,在所有设备中都没有-I选项,在我的情况下返回127.0.0.1。
如果你知道网络接口(eth0, wlan, tun0等):
ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2
在一个默认网关的网络中查找这台计算机的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
使用grep从ifconfig中过滤IP地址:
ifconfig | grep eo的inet (addr:) ?([0 - 9] * \){3}[0 - 9] *’| grep eo”([0 - 9]* \){3}[0 - 9]*’| grep - v 127.0.0.1的
或者用sed:
ifconfig | sed -En 's/127.0.0.1//;* inet (addr) ?(([0 - 9] * \){3}[0 - 9] *)。* / \ 2 / p”
如果你只对某些接口感兴趣,比如wlan0、eth0等,那么:
ifconfig wlan0 | ...
例如,您可以在.bashrc中使用别名来创建自己的命令myip。
别名myip =“ifconfig | sed -En’s / 127 . 0 0。1;s /。* inet(键入https://www.bittrex.com:) ?(0 - 9) *[\。)0 - 9]{3}[*)* \ 2 / p’”。
一个更简单的方法是hostname -I (hostname -I用于旧版本的hostname,但请参阅注释)。但是,这仅适用于Linux。
我浏览了很多链接(StackExchange, AskUbuntu, StackOverflow等),并决定将所有最好的解决方案合并到一个shell脚本中。
在我看来,这两个qa是我见过的最好的:
如何在shell脚本中获得我的外部IP地址? https://unix.stackexchange.com/q/22615
我如何找到我的内部ip地址? https://askubuntu.com/a/604691
下面是基于rsp在他的存储库(https://github.com/rsp/scripts/)中分享的一些想法的解决方案。
有些人可能会说这个脚本对于这么简单的任务来说是非常大的,但我想让它在使用时尽可能地简单和灵活。它支持简单的配置文件,允许重新定义默认值。
它在Cygwin, MINGW和Linux (Red Hat)下成功测试。
显示内部IP地址
myip -i
显示外部IP地址
myip -e
源代码,也可通过链接:https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip。配置文件的示例在那里,在主脚本旁边。
#!/bin/bash
# =========================================================================
#
# Getting both internal and external IP addresses used for outgoing
# Internet connections.
#
# Internal IP address is the IP address of your computer network interface
# that would be used to connect to Internet.
#
# External IP address is the IP address that is visible by external
# servers that you connect to over Internet.
#
# Copyright (C) 2016 Ildar Shaimordanov
#
# =========================================================================
# Details of the actual implementation are based on the following QA:
#
# How can I get my external IP address in a shell script?
# https://unix.stackexchange.com/q/22615
#
# How do I find my internal ip address?
# https://askubuntu.com/a/604691
# =========================================================================
for f in \
"$( dirname "$0" )/myip.conf" \
~/.myip.conf \
/etc/myip.conf
do
[ -f "$f" ] && {
. "$f"
break
}
done
# =========================================================================
show_usage() {
cat - <<HELP
USAGE
$( basename "$0" ) [OPTIONS]
DESCRIPTION
Display the internal and external IP addresses
OPTIONS
-i Display the internal IP address
-e Display the external IP address
-v Turn on verbosity
-h Print this help and exit
HELP
exit
}
die() {
echo "$( basename "$0" ): $@" >&2
exit 2
}
# =========================================================================
show_internal=""
show_external=""
show_verbose=""
while getopts ":ievh" opt
do
case "$opt" in
i )
show_internal=1
;;
e )
show_external=1
;;
v )
show_verbose=1
;;
h )
show_usage
;;
\? )
die "Illegal option: $OPTARG"
;;
esac
done
if [ -z "$show_internal" -a -z "$show_external" ]
then
show_internal=1
show_external=1
fi
# =========================================================================
# Use Google's public DNS to resolve the internal IP address
[ -n "$TARGETADDR" ] || TARGETADDR="8.8.8.8"
# Query the specific URL to resolve the external IP address
[ -n "$IPURL" ] || IPURL="ipecho.net/plain"
# Define explicitly $IPCMD to gather $IPURL using another tool
[ -n "$IPCMD" ] || {
if which curl >/dev/null 2>&1
then
IPCMD="curl -s"
elif which wget >/dev/null 2>&1
then
IPCMD="wget -qO -"
else
die "Neither curl nor wget installed"
fi
}
# =========================================================================
resolveip() {
{
gethostip -d "$1" && return
getent ahostsv4 "$1" \
| grep RAW \
| awk '{ print $1; exit }'
} 2>/dev/null
}
internalip() {
[ -n "$show_verbose" ] && printf "Internal: "
case "$( uname | tr '[:upper:]' '[:lower:]' )" in
cygwin* | mingw* | msys* )
netstat -rn \
| grep -w '0.0.0.0' \
| awk '{ print $4 }'
return
;;
esac
local t="$( resolveip "$TARGETADDR" )"
[ -n "$t" ] || die "Cannot resolve $TARGETADDR"
ip route get "$t" \
| awk '{ print $NF; exit }'
}
externalip() {
[ -n "$show_verbose" ] && printf "External: "
eval $IPCMD "$IPURL" $IPOPEN
}
# =========================================================================
[ -n "$show_internal" ] && internalip
[ -n "$show_external" ] && externalip
# =========================================================================
# EOF