哪个终端命令只能得到 IP 地址而不能得到其他信息?

我试图在我编写的脚本中只使用 IP 地址(inet)作为参数。

在 unix 终端中有没有一种简单的方法只获取 IP 地址,而不是通过 ifconfig查找?

258025 次浏览

你可以编写一个只返回 IP 的脚本,比如:

/sbin/ifconfig eth0 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}'

对于 MAC:

ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\  -f2

或者 Linux 系统

hostname -i | awk '{print $3}' # Ubuntu


hostname -i # Debian

我将使用 Hostname -L来获得只是作为一个变量在脚本中使用的 IP。

使用以下命令:

/sbin/ifconfig $(netstat -nr | tail -1 | awk '{print $NF}') | awk -F: '/inet /{print $2}' | cut -f1 -d ' '

下面是我的版本,其中您可以传递按优先级排序的接口列表:

getIpFromInterface()
{
interface=$1
ifconfig ${interface}  > /dev/null 2>&1 && ifconfig ${interface} | awk -F'inet ' '{ print $2 }' | awk '{ print $1 }' | grep .
}


getCurrentIpAddress(){
IFLIST=(${@:-${IFLIST[@]}})
for currentInterface in ${IFLIST[@]}
do
IP=$(getIpFromInterface  $currentInterface)
[[ -z "$IP" ]] && continue
echo ${IP/*:}
return
done
}


IFLIST=(tap0 en1 en0)
getCurrentIpAddress $@

因此,如果我连接到 VPN,Wifi 和以太网,我的 VPN 地址(在接口 tap0)将被返回。这个脚本同时适用于 linux 和 osx,如果您想覆盖 IFLIST,它可以接受参数

请注意,如果您想使用 IPV6,您必须将“ inet”替换为“ inet6”。

一般来说,不能保证一个系统只有一个 IP 地址,例如,您可以同时拥有一个以太网和 wlan 连接,如果您拥有一个活动的 VPN 连接,那么您将拥有另一个 IP 地址。

Linux

在 Linux 上,hostname -I将列出当前的 IP 地址。依赖它总是只返回一个 IP 地址在某些情况下很可能不会像预期的那样工作(比如 VPN 链接启动,多个以太网适配器,等等) ,所以一个更可靠的方法是将结果转换成一个数组,然后在元素之间循环:

ips=($(hostname -I))


for ip in "${ips[@]}"
do
echo $ip
done

注意 : 如果 hostname -I返回 IPv4和 IPv6格式的 IP,那么可以使用 hostname -I | cut -f1 -d' '仅显示 IPv4 IP。

OSX

在 OSX 和 如果你知道界面的话上,你可以使用:

~$ ipconfig getifaddr en0
# OUTPUT: 192.168.1.123

它将返回 只是的 IP 地址。

要动态检测 MacOS 上的(第一个)活动网络接口:

network_device=$(scutil --dns |awk -F'[()]' '$1~/if_index/ {print $2;exit;}')
ip=$(ipconfig getifaddr "$network_device")
echo $ip
### OUTPUT: 192.168.1.123

另外,当一台机器有多个以太网接口,或者当 VPN 隧道建立起来时,获取 IP 地址变得不确定。

获取外部 IP

如果您需要外部 IP,那么您可以查询一个文本模式的服务,例如 curl https://ipecho.net/plain将返回一个纯文本 外部 IP。

一个可能更快的替代方法是查询一个已知的 DNS 服务器,例如:

dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short

要获得 Mac OS X上的 IP 地址,您可以键入以下命令:

ipconfig getifaddr en0

这将为您提供所有 IPv4接口,包括环回127.0.0.1:

ip -4 addr | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

这将只显示 eth0:

ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

这样你就可以得到 IPv6地址:

ip -6 addr | grep -oP '(?<=inet6\s)[\da-f:]+'

只有 eth0 IPv6:

ip -6 addr show eth0 | grep -oP '(?<=inet6\s)[\da-f:]+'

我总是在最意想不到的时候需要它,并且,毫无疑问,在 SO 上搜索这样的线程。因此,我编写了一个简单的脚本,通过 netstat 获取 IPv4地址,称为 echoip-你可以在这里找到。网络地址的 bash 看起来像这样,它也可以从 ipecho.net 获取你的公共地址:

IPV4='\d+(\.\d+){3}'
INTERFACES=`netstat -i | grep -E "$IPV4" | cut -d ' ' -f 1`
INTERFACE_IPS=`netstat -i | grep -oE "$IPV4"`


for i in "${!INTERFACES[@]}"; do
printf "%s:\t%s\n" "${INTERFACES[$i]}" "${INTERFACE_IPS[$i]}"
done

echoip脚本生成如下输出:

$ echoip
public: 26.106.59.169
en0:    10.1.10.2

我想要一个简单的 Bash 化名。我发现 hostname -I最适合我(主机名 v3.15)。由于某种原因,hostname -i返回了环回 IP,但是 hostname -I为 wlan0提供了正确的 IP,而且不需要通过 grep 或 awk 管道输出。缺点是,如果您有多个 所有 IP,则 hostname -I将输出 所有 IP。

我们只需使用两个命令(ifconfig + awk)就可以得到我们想要的 IP (v4) ,如下所示:

在 Linux 上,假设从 eth0接口获取 IP 地址,运行以下命令:

/sbin/ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

在 OSX 上,假设要从 en0接口获取 IP 地址,运行以下命令:

/sbin/ifconfig en0 | awk '/inet /{print $2}'

要了解我们的公共/外部 IP,请在 ~/.bashrc中添加此函数

whatismyip () {
curl -s "http://api.duckduckgo.com/?q=ip&format=json" | jq '.Answer' | grep --color=auto -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
}

那就跑,whatismyip

ip addr|awk '/eth0/ && /inet/ {gsub(/\/[0-9][0-9]/,""); print $2}'

显示你所有的 IP 地址

在最新的 Ubuntu版本(14.04-16.04)中,这个命令帮了我大忙。

hostname -I | awk '{print $1}'
hostname -I

这个命令会给你在 Ubuntu 中你想要的精确的 ip 地址。

使用这一行脚本: Ifconfig | grep“ inet”| grep-v 127.0.0.1 | awk‘ match ($0,/([0-9] + . [0-9] + . [0-9] + . [0-9] +)/){ print subr ($0,RSTART,RLENGTH)}’ Mac 和 linux (在 ubuntu 中测试)都可以工作。

在 Redhat 64位上,这为我解决了问题。

ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'

如果环境有限,可以使用以下命令:

ip -4 addr show dev eth0 | grep inet | tr -s " " | cut -d" " -f3 | head -n 1

这在苹果电脑上就能奏效:

ping $(ifconfig en0 | awk '$1 == "inet" {print $2}')

解决了 ping 192.168.1.2在我的机器。

专业提示 : $(...)表示运行子 shell 中括号内的任何内容,并将其作为值返回。

命令 ifconfig不被推荐,您应该在 Linux 上使用 ip命令。

而且 ip a将在与 IP 相同的行上为您提供作用域,因此更容易使用。

这个命令将显示您的全局(外部) IP:

ip a | grep "scope global" | grep -Po '(?<=inet )[\d.]+'

所有 IPv4(也是127.0.0.1) :

ip a | grep "scope" | grep -Po '(?<=inet )[\d.]+'

所有 IPv6(也是: : 1) :

ip a | grep "scope" | grep -Po '(?<=inet6 )[\da-z:]+'
curl ifconfig.co

这只返回系统的 ip 地址。

man hostname中,还有一种更简单的方法,可以自动排除环回 IP,只显示分配给主机 IP 地址的空间分隔列表:

root@srv:~# hostname --all-ip-addresses
11.12.13.14 192.168.15.19


root@srv:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/void
inet 11.12.13.14/32 scope global venet0:0
inet 192.168.15.19/32 scope global venet0:1

您还可以使用以下命令:

ip route | grep src

注意: 这只有在你连接到互联网的情况下才有效。

#!/bin/sh
# Tested on Ubuntu 18.04 and Alpine Linux
# List IPS of following network interfaces:
# virtual host interfaces
# PCI interfaces
# USB interfaces
# ACPI interfaces
# ETH interfaces
for NETWORK_INTERFACE in $(ls /sys/class/net -al | grep -iE "(/eth[0-9]+$|vif|pci|acpi|usb)" | sed -E "s@.* ([^ ]*) ->.*@\1@"); do
IPV4_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet addr[: ]+|inet[: ]+)' | sed -E "s@\s*(inet addr[: ]+|inet[: ]+)([^ ]*) .*@\2@")
IPV6_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet6 addr[: ]+|inet6[: ]+)' | sed -E "s@\s*(inet6 addr[: ]+|inet6[: ]+)([^ ]*) .*@\2@")
if [ -n "$IPV4_ADDRESSES" ] || [ -n "$IPV6_ADDRESSES" ]; then
echo "NETWORK INTERFACE=$NETWORK_INTERFACE"
for IPV4_ADDRESS in $IPV4_ADDRESSES; do
echo "IPV4=$IPV4_ADDRESS"
done
for IPV6_ADDRESS in $IPV6_ADDRESSES; do
echo "IPV6=$IPV6_ADDRESS"
done
fi
done

当在 NATed 主机上查找外部 IP 地址时,相当多的答案建议使用基于 HTTP 的方法,如 ifconfig.me,例如:

$ curl ifconfig.me/ip

这些年来,我看到许多这样的网站来来去去,我发现这种基于 DNS 的方法更加健壮:

$ dig +short myip.opendns.com @resolver1.opendns.com

我在 ~/.bashrc里有个化名:

alias wip='dig +short myip.opendns.com @resolver1.opendns.com'

只打印 eth0的 IP 地址,不打印其他文本:

ifconfig eth0 | grep -Po '(?<=inet addr:)[\d.]+'

要确定主接口(因为它可能不是“ eth0”) ,请使用:

route | grep ^default | sed "s/.* //"

以上两行可以组合成一个命令,如下所示:

ifconfig `route | grep ^default | sed "s/.* //"` \
| grep -Po '(?<=inet addr:)[\d.]+'

很少有答案似乎是使用新的 ip命令(取代 ifconfig) ,所以这里有一个使用 ip addrgrepawk简单地打印与 wlan0接口相关的 IPv4地址:

ip addr show wlan0|grep inet|grep -v inet6|awk '{print $2}'|awk '{split($0,a,"/"); print a[1]}'

虽然不是最紧凑或最花哨的解决方案,但它(可以说)很容易理解(参见下面的解释) ,并为其他目的进行修改,比如获取 MAC 地址的最后3个八进制字节,如下所示:

ip addr show wlan0|grep link/ether|awk '{print $2}'|awk '{split($0,mac,":"); print mac[4] mac[5] mac[6]}'

说明: ip addr show wlan0输出与名为 wlan0的网络接口相关的信息,这应该类似于:

4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether dc:a6:32:04:06:ab brd ff:ff:ff:ff:ff:ff
inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0
valid_lft forever preferred_lft forever
inet6 fe80::d340:5e4b:78e0:90f/64 scope link
valid_lft forever preferred_lft forever

接下来,grep inet过滤掉不包含“ inet”(IPv4和 IPv6配置)的行,grep -v inet6过滤掉 包含“ inet6”的剩余行,这应该会产生下面这样一行:

    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0

最后,第一个 awk提取“172.18.18.1/24”字段,第二个删除网络掩码速记,只保留 IPv4地址。

另外,我认为值得一提的是,如果您正在编写脚本,那么通常会有许多更丰富和/或更健壮的工具来获取这些信息,您可能希望使用这些工具。例如,如果使用 Node.js 就有 ipaddr-linux,如果使用 Ruby 就有 linux-ip-parser,等等。

参见 https://unix.stackexchange.com/questions/119269/how-to-get-ip-address-using-shell-script

我不喜欢在脚本中使用 awk等等. . ip可以选择以 JSON 格式输出。

如果你省略了 $interface,那么你就得到了所有的 IP 地址:

ip -json addr show $interface | \
jq -r '.[] | .addr_info[] | select(.family == "inet") | .local'

这两种方法对我很有效:

要获取接口 eth0的 IP 地址,请将下面示例中的 eth0替换为接口名称。 ifconfig eth0 | grep -w "inet" | tr -s " " | cut -f3 -d" "

使用主机名: 这将给你的内阁,即 IPAddress 的你的精神。Using-我将给出所有接口的 inet 值,无论这个值出现在哪里。

hostname -i

我没有看到任何答案与 nmcli,这是一个控制网络管理器的命令行工具。

给你:)

wolf@linux:~$ nmcli device
DEVICE  TYPE      STATE        CONNECTION
eth1    ethernet  unavailable  --
eth0    ethernet  unmanaged    --
lo      loopback  unmanaged    --
wolf@linux:~$

如果希望从特定的网络接口获取信息(例如 lo)

wolf@linux:~$ nmcli device show lo
GENERAL.DEVICE:                         lo
GENERAL.TYPE:                           loopback
GENERAL.HWADDR:                         00:00:00:00:00:00
GENERAL.MTU:                            65536
GENERAL.STATE:                          10 (unmanaged)
GENERAL.CONNECTION:                     --
GENERAL.CON-PATH:                       --
IP4.ADDRESS[1]:                         127.0.0.1/8
IP4.GATEWAY:                            --
IP4.ROUTE[1]:                           dst = 127.0.0.0/8, nh = 0.0.0.0,>
IP4.ROUTE[2]:                           dst = 127.0.0.1/32, nh = 0.0.0.0>
IP6.ADDRESS[1]:                         ::1/128
IP6.GATEWAY:                            --
IP6.ROUTE[1]:                           dst = ::1/128, nh = ::, mt = 256
IP6.ROUTE[2]:                           dst = ::1/128, nh = ::, mt = 0, >
wolf@linux:~$

但是因为您只想获得 IP 地址,所以只需将输出发送到 grepcutawk

让我们一步一步来。(不知道出了什么问题,代码示例格式对这3个示例不起作用。)

  1. 接通 IPv4网络

    Wolf@linux: ~ $nmcli device show lo | grep 4. A IP4.Address [1] : 127.0.0.1/8 Wolf@linux: ~ $

  2. 使用 awk获取 IP

    Wolf@linux: ~ $nmcli 设备显示 lo | awk’/4. A/{ print $2}’ 127.00.1/8 Wolf@linux: ~ $

  3. 使用 cut删除 CIDR 表示法(/8)

    Wolf@linux: ~ $nmcli device show lo | awk’/4. A/{ print $2}’| cut-d/-f1 127.0.0.1 Wolf@linux: ~ $

这就是你的答案。

请注意,使用我刚才演示的工具有很多方法可以做到这一点。

让我们回顾一下我使用的命令。

nmcli device show lo | grep 4.A
nmcli device show lo | awk '/4.A/ {print $2}'
nmcli device show lo | awk '/4.A/ {print $2}' | cut -d / -f1

这3个命令的示例输出

命令1输出

IP4.ADDRESS[1]:                         127.0.0.1/8

命令2输出

127.0.0.1/8

命令3输出

127.0.0.1

如果您不想使用 ifconfig或 regex..。

ip addr | grep eth0 | grep inet | awk '{print $2}' | cut -d"/" -f1

默认路由的 IPv4地址:

ip address show $(ip route | grep "^default " | head -n1 | grep -Po "(?<=dev )[^ ]+") | grep -Po "(?<=inet )[^ /]+"

默认路由的 IPv6地址:

ip address show $(ip route | grep "^default " | head -n1 | grep -Po "(?<=dev )[^ ]+") | grep -Po "(?<=inet6 )[^ /]+"

这些只需要支持 -P-o的命令 ipgrephead -1是必需的,因为当系统有足够复杂的网络设置时,ip route可能会显示多个默认路由。

如果你不介意哪个 IP 是哪个,你可以直接做

ip route | grep -Po '(?<=src )[^ ]+'

或者

hostname --all-ip-addresses

最简单的方法就是像 米可说的那样

hostname --all-ip-addresses

输出 enter image description here

你也可以这样做,了解更多的细节:

ip route

输出 enter image description here

Ip adddr,短路

ip -4 -br addr show enp1s0 | awk -F" " '{print $3}'|cut -d'/' -f1

或者缩短

ip -4 -br a s enp1s0 | awk -F" " '{print $3}'|cut -d'/' -f1

必须在大多数现代 Linux 发行版中工作

如果你指的是可移植到嵌入式 Linux 操作系统的“ Linux”还有:

ip route get 8.8.8.8 | head -n 1 | tr -s ' ' | cut -d ' ' -f 7

这样就不需要调用 awk,因为它并没有安装在所有嵌入式 Linux 上。Awk 只是从字符串中获取字段的过程有点繁琐。

每个 Linux 环境都将提供 tr、 head 和 cut。如果嵌入式环境真的很旧,它可能只有“ ifconfig”,但是您可以看到这里的图片: 获取行,删除填充,剪切您需要的内容。

ip -4 addr show eth0在一些机器上不能工作。例如,我得到这个错误: ip: symbol lookup error: ip: undefined symbol: bpf_program__section_name, version LIBBPF_0.2.0

这对我有用:

/sbin/ifconfig eth0 | grep 'inet ' | awk '{ print $2}'

这比接受的答案少了一个管道。此外,我的 ifconfig 输出没有 inet addr

要获取 IPv6地址,请使用以下方法:

/sbin/ifconfig eth0 | grep 'inet6 ' | awk '{ print $2}'