提取IP地址的Linux bash脚本

提取IP地址的Linux bash脚本,linux,bash,sed,awk,Linux,Bash,Sed,Awk,我想在我的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:

我想在我的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“您的IP地址是:(IP_地址)”。是否有任何命令允许我做这样的事情,在流中搜索我想要得到的信息?。我知道
grep
sed
但我对它们不是很在行


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

只需获取您的IP地址:

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`
ifconfig eth0 2>/dev/null sed -n 's/.*[[:space:]]\([[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\).*/\1/p'
这将为您提供eth0的IP地址

编辑:由于Ubuntu最新版本中接口的名称发生了变化,这不再有效。相反,您可以使用以下方法:


hostname——所有ip地址
hostname-I
,其作用相同(提供主机的所有ip地址)。

如果目标是找到与internet方向连接的ip地址,那么这应该是一个很好的解决方案

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


要找到连接到internet的IP加法器,我们可以使用
IP路由
命令。对于较新版本的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之后使用awksedgrep查找IP

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
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

其他解决方案可能失败的原因:

ifconfig eth0

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

  • 可能只会得到127.0.1.1
  • 不适用于所有系统
  • 提供所有IP,而不仅仅是连接到internet的IP-一、 --所有ip地址主机的所有地址
选择:

$ 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

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


正如这里所描述的:?

只是一个注释,因为我只是花了一些时间来解决服务器升级失败的问题。 事实证明,(几年前)我实施了一个测试,以查看是否存在动态添加的接口(例如eth0:1),如果存在,我会将某些proggis绑定到eth0上的“main”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>
嗯,反正是这样的。由于所有建议的解决方案似乎都存在失败的情况,请检查可能的边缘情况-无eth、多个eth和lo、何时“主机名-i”会失败,。。。然后决定最佳解决方案,检查它是否有效,否则为第二最佳

干杯,啤酒

ip-4 addr show eth0 | grep-oP”(?可能不适用于所有情况(特别是如果您有多个NIC),这将有助于:

ip route get 8.8.8.8| grep src| sed 's/.*src \(.* \)/\1/g'|cut -f1 -d ' '
hostname -I | awk '{ print $1 }'

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

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

ip路由获取[主机]
-提供用于访问远程主机的网关,例如:

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路由…
解决方案进行了轻微修改,消除了对grep的需要:

ip route get 8.8.8.8 | sed -n 's|^.*src \(.*\)$|\1|gp'

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

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`
ifconfig eth0 2>/dev/null sed -n 's/.*[[:space:]]\([[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\).*/\1/p'

还可以查看man bash中管道的文档。您尝试执行的操作中存在一个基本问题:机器通常可以有多个IP地址(一个用于有线连接,一个用于无线连接,一个用于虚拟机连接,等等)。你需要考虑你想要哪一个。@JamesKingsbery我没有考虑这个问题。我以后会考虑。谢谢你给我看下一个问题。PS:谢谢你给我发来了man grep参考。它真的很有帮助。
echo
什么都没做。而且自从awk c以来,你再也不需要
sed
awk
sed可以做任何事情。您不应该使用旧的,使用括号
$(code)
。如果不是eth0,它也会失败。可以这样写:
ifconfig eth0 | awk-F“[:]+”/inet addr://{print$4}“
考虑使用
hostname-I
。根据@DanilaV.的评论。现在NIC的命名可能不是ethX,很多版本的linux已经开始使用em作为接口前缀。在Ubuntu>=
15.x
中,他们已经将接口从
eth0
重命名为
eno1
,所以这个脚本根本不起作用。谢谢您的支持备注。我在解决方案中添加了“主机名--所有ip地址”,这与主机名-I相同(谢谢icdevppl!)。您在这里提到的命令非常好,但我的项目仍在进行中,我不是100%需要的。不会总是得到一个IP。在我的VPS服务器上,我得到这个输出
127.0.2 143.127.52.130 2a00:dee0:ed3:83:245:70:fc12:d196
,因此我需要添加一些过滤器。@Jotne如果您有多个IP,您可以剪切输出t到您想要的一个(例如第一个)如下:
hostname-I | cut-f1-d'
,尽管我同意如果接口的顺序可以改变,那么使用
ip
工具会更好-假设只有一个地址,这是完美的!下面是另一个通过“ip”I获得它的简单方法
8.8.8.8 via 192.168.0.1 dev enp0s3 src 192.168.0.109
192.168.0.109
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
ifconfig eth0 2>/dev/null sed -n 's/.*[[:space:]]\([[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\).*/\1/p'