繁体   English   中英

Linux bash脚本提取IP地址

[英]Linux bash script to extract IP address

我想在我的 Debian 7.3 上制作大脚本(类似于翻译的内容和更多新的用户友好环境)。 我有个问题。 我只想使用命令给我的一些信息。 例如我的 ifconfig 看起来像:

eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0  
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1309425 (1.2 MiB)  T

我只想在行中显示 IP 地址: echo "Your IP address is: (IP_ADDRESS )"。 有没有任何命令可以让我做这样的事情,在 stream 中搜索我想要获取的信息? 我知道grepsed但我对它们不是很好。

编辑:首先要感谢您帮助我解决这个问题,现在我知道更多了。 其次说项目正在进行中。 如果有人对它感兴趣,请pm我。

如果目标是找到互联网方向连接的IP地址,那么这应该是一个很好的解决方案。

2021 年编辑:添加了“sed”和“grep”版本以及新的“awk”版本(有些是 gnu)


要查找连接到 Internet 的ip route ,我们可以使用ip route命令。 使用较新版本的 Linux,您可以通过如下典型输出获得更多信息:

ip route get 8.8.8.8
8.8.8.8 via 10.36.15.1 dev ens160 src 10.36.15.150 uid 1002
    cache

所以要获得IP,您需要在src之后找到 IP,使用awksedgrep

ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/src (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/src/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*src (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*src \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?src (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'src \K[^ ]+'
10.36.15.150

如果您喜欢使用awksedgrep接口名称

ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/dev (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*?dev (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*dev \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?dev (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'dev \K[^ ]+'
ens192

ip route不会打开任何连接,它只显示到达8.8.8.8所需的路由。 8.8.8.8是谷歌的 DNS。

如果您想将其存储到变量中,请执行以下操作:

my_ip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

my_interface=$(ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}')

为什么其他解决方案可能会失败:

ifconfig eth0

  • 如果您拥有的接口有另一个名称(eno1、wifi、venet0 等)
  • 如果您有多个接口
  • IP连接方向不是多个IF列表中的第一个

Hostname -I

  • 可能只得到 127.0.1.1
  • 不适用于所有系统。
  • 给所有 IP 不仅是连接到互联网的 IP。 -I, --all-ip-addresses 主机的所有地址

要获取您的 IP 地址:

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`

这将为您提供 eth0 的 IP 地址。

编辑:由于最近版本的 Ubuntu 中接口的名称更改,这不再起作用。 相反,你可以使用这个:

hostname --all-ip-addresseshostname -I ,它们做同样的事情(给你主机的所有 IP 地址)。

如果您想获取以空格分隔的 IP 列表,您可以使用带有--all-ip-addresses (short -I ) 标志的hostname命令

hostname -I

如此处所述: 将 IP 地址放入 bash 变量。 有更好的方法吗?

ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)"

可能不适用于所有情况(特别是如果您有多个 NIC),这将有所帮助:

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

随你挑:

$ cat file
eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1309425 (1.2 MiB)  T

$ awk 'sub(/inet addr:/,""){print $1}' file
192.168.1.103

$ awk -F'[ :]+' '/inet addr/{print $4}' file
192.168.1.103
  /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
ip route get 8.8.8.8| grep src| sed 's/.*src \(.* \)/\1/g'|cut -f1 -d ' '

请注意,因为我只是花了一些时间对服务器上的拙劣升级进行故障排除。 原来,那(几年前)我已经实施了一项测试,以查看是否存在动态添加的接口(例如 eth0:1),如果存在,我会将某些 proggis 绑定到 eth0 上的“主”IP。 基本上它是 'ifconfig|grep...|sed...' 解决方案的变体(加上检查 'eth0:' 的存在)。
升级带来了新的网络工具,输出也略有变化:

旧的 ifconfig:

eth0      Link encap:Ethernet  HWaddr 42:01:0A:F0:B0:1D
          inet addr:10.240.176.29  Bcast:10.240.176.29  Mask:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          ...<SNIP>

而新版本将显示:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1460
      inet 10.240.212.165  netmask 255.255.255.255  broadcast 10.240.212.165
      ...<SNIP>

渲染对 'eth0:' 和 'inet addr:' 的搜索失败(不要介意名为 'em0'、'br0' 或 'wlan0' 的接口......)。 当然,您可以检查“inet”(或“inet6”),并使 addr: 部分可选,但仔细观察,您会发现或多或少一切都发生了变化,“Mask”现在是“netmask”,.. .

'ip route ...' 建议非常漂亮 - 所以也许:

_MyIP="$( ip route get 8.8.8.8 | awk 'NR==1 {print $NF}' )"
if [ "A$_MyIP" == "A" ]
then
    _MyIPs="$( hostname -I )"
    for _MyIP in "$_MyIPs"
    do
        echo "Found IP: \"$_MyIP\""
    done
else
    echo "Found IP: $_MyIP"
fi

好吧,无论如何都是这样的。 由于所有提议的解决方案似乎都有失败的情况,请检查可能的边缘情况 - 没有 eth,多个 eth 和 lo,'hostname -i' 何时会失败,...然后决定最佳解决方案,检查它是否有效,否则第二个最好。

干杯'n'啤酒!

在我看来,实现您所需要的最简单、最优雅的方法是:

ip route get 8.8.8.8 | tr -s ' ' | cut -d' ' -f7

ip route get [host] - 为您提供用于访问远程主机的网关,例如:

8.8.8.8 via 192.168.0.1 dev enp0s3  src 192.168.0.109

tr -s ' ' - 删除任何额外的空格,现在你有统一性,例如:

8.8.8.8 via 192.168.0.1 dev enp0s3 src 192.168.0.109

cut -d' ' -f7 - 将字符串截断为 ' ' 空格分隔的字段,然后从中选择字段 #7,例如:

192.168.0.109

对以前的ip route ...解决方案之一稍作修改,从而消除了对 grep 的需要:

ip route get 8.8.8.8 | sed -n 's|^.*src \(.*\)$|\1|gp'
awk '/inet addr:/{gsub(/^.{5}/,"",$2); print $2}' file
192.168.1.103

如果您只想使用 sed 来提取 IP 地址:

ifconfig eth0 2>/dev/null sed -n 's/.*[[:space:]]\([[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\).*/\1/p'

对以前的ip route...仅使用ipsed并正确隔离 IPv4 ZA12A3907BE8 的解决方案

ip -4 route get 1.1.1.1 | sed -n 's/^.*src \([0-9.]*\).*$/\1/p'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM