Linux bash脚本提取IP地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21336126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:54:38  来源:igfitidea点击:

Linux bash script to extract IP address

linuxbashsedawk

提问by user3232381

I want to make big script on my Debian 7.3 ( something like translated and much more new user friendly enviroment ). I have a problem. I want to use only some of the informations that commands give me. For example my ifconfig looks like:

我想在我的 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

I want to display only the IP address in line: echo "Your IP address is: (IP_ADDRESS )". Is there any command that allow me to do such a thing, to search in stream for informations I want to get?. I know about grepand sedbut I am not really good with them.

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

Edit: Firstly to say thank you for helping me with this problem, now I know much more. Secondly to say project is in progress. If anyone would be interested in it just pm me.

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

采纳答案by Marco Hegenberg

To just get your IP address:

要获取您的 IP 地址:

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

This will give you the IP address of eth0.

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

Edit: Due to name changes of interfaces in recent versions of Ubuntu, this doesn't work anymore. Instead, you could just use this:

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

hostname --all-ip-addressesor hostname -I, which does the same thing (gives you ALL IP addresses of the host).

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

回答by Jotne

If the goal is to find the IP addressconnected in direction of internet, then this should be a good solution.

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



UPDATE!!! With new version of linux you get more information on the line:

更新!!!使用新版本的 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

so to get IP you need to find the IP after src

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

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

and if you like the interface name

如果你喜欢接口名称

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

ip routedoes not open any connection out, it just shows the route needed to get to 8.8.8.8. 8.8.8.8is Google's DNS.

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

If you like to store this into a variable, do:

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

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

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


Why other solution may fail:

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

ifconfig eth0

ifconfig eth0

  • If the interface you have has another name (eno1, wifi, venet0 etc)
  • If you have more than one interface
  • IP connecting direction is not the first in a list of more than one IF
  • 如果您拥有的接口有另一个名称(eno1、wifi、venet0 等)
  • 如果您有多个接口
  • IP连接方向不是多个IF列表中的第一个

Hostname -I

Hostname -I

  • May get only the 127.0.1.1
  • Does not work on all systems.
  • 可能只得到 127.0.1.1
  • 不适用于所有系统。

回答by Ed Morton

Take your pick:

随你挑:

$ 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 }' file
192.168.1.103

$ awk -F'[ :]+' '/inet addr/{print }' file
192.168.1.103

回答by user000001

If you want to get a space separated list of your IPs, you can use the hostnamecommand with the --all-ip-addresses(short -I) flag

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

hostname -I

as described here: Putting IP Address into bash variable. Is there a better way?

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

回答by Tharanga Abeyseela

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

回答by Kevin

Just a note, since I just spent some time trouble-shooting a botched upgrade on a server. Turned out, that (years ago) I had implemented a test to see if dynamically added interfaces (e.g. eth0:1) were present, and if so, I would bind certain proggis to the 'main' IP on eth0. Basically it was a variation on the 'ifconfig|grep...|sed... ' solution (plus checking for 'eth0:' presence).
The upgrade brought new net-tools, and with it the output has changed slightly:

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

old ifconfig:

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

whereas the new version will display this:

而新版本将显示:

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>

rendering the hunt for 'eth0:' as well as 'inet addr:' search busted (never mind interfaces called 'em0','br0' or 'wlan0'...). Sure you could check for 'inet ' (or 'inet6'), and make the addr: part optional, but looking closer, you'll see that more or less everything has changed, 'Mask' is now 'netmask',...

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

The 'ip route ...' suggestion's pretty nifty - so maybe:

'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

Well, something of that sort anyway. Since all proposed solutions seem to have circumstances where they fail, check for possible edge cases - no eth, multiple eth's & lo's, when would 'hostname -i' fail,... and then decide on best solution, check it worked, otherwise 2nd best.

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

Cheers 'n' beers!

干杯'n'啤酒!

回答by fastrizwaan

ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$//g'

回答by John

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

回答by Pavel

May be not for all cases (especially if you have several NIC's), this will help:

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

hostname -I | awk '{ print  }'

回答by Leonardo

In my opinion the simplest and most elegant way to achieve what you need is this:

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

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


ip route get [host]- gives you the gateway used to reach a remote host e.g.:

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

8.8.8.8 via 192.168.0.1 dev enp0s3  src 192.168.0.109


tr -s ' '- removes any extra spaces, now you have uniformity e.g.:

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

8.8.8.8 via 192.168.0.1 dev enp0s3 src 192.168.0.109


cut -d' ' -f7- truncates the string into ' 'space separated fields, then selects the field #7 from it e.g.:

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

192.168.0.109