将IP地址放入bash变量中。有更好的方法吗?

46

我正试图找到一种简短而健壮的方法将我的IP地址放入bash变量中,我想知道是否有更简单的方法。下面是我目前的做法:

ip=`ifconfig|xargs|awk '{print $7}'|sed -e 's/[a-z]*:/''/'`

你是如何添加反引号的? - user583507
4
如果在一行前面加上4个空格,则会被视为代码,这时反引号不会被处理。 - woliveirajr
20个回答

3
以下内容适用于Mac OS(其中没有ip命令或主机名选项):
#!/bin/bash

#get interface used for defalt route (usually en0)
IF=$(route get default |grep 'interface' |awk -F: '{print $2}');

#get the IP address for inteface IF
#does ifconfig, greps for interface plus 5 lines, greps for line with 'inet '
IP=$(ifconfig |grep -A5 $IF | grep 'inet ' | cut -d: -f2 |awk '{print $2}');
#get the gateway for the default route
GW=$(route get default | awk '/gateway:/ {print $2}');

2
我认为最可靠的答案是:
ifconfig  | grep 'inet addr:' | grep -v '127.0.0.1' | awk -F: '{print $2}' | awk '{print $1}' | head -1

并且

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

因为当你不使用 head -1 时,它会显示所有的IP地址....

2
我正在使用。
IFACE='eth0'
IP=$(ip -4 address show $IFACE | grep 'inet' | sed 's/.*inet \([0-9\.]\+\).*/\1/')

这种方式的优点是可以指定接口(例如示例中的变量IFACE),以防您在主机上使用多个接口。
此外,您可以修改ip命令,以便根据需要调整此代码片段(如IPv6地址等)。

2

在我的脚本中,我只需要IP地址的网络部分,所以我像这样做:

local=$(hostname -I | awk '{print $2}' | cut -f1,2,3 -d".")

在“cut -f1,2,3 -d'.'”中,“-f1,2,3”表示获取以逗号分隔的前3个部分,“-d'.'”表示以句点作为分隔符。

要更改接口,请将“$2”更改为您的接口编号;要获取整个IP,请删除“cut”命令。


1
在Mac OSX上,您可以使用ipconfig getifaddr [interface]命令来获取本地IP地址:
$ ipconfig getifaddr en0
192.168.1.30

$ man ipconfig 

DESCRIPTION
     ipconfig is a utility that communicates with the IPConfiguration agent to
     retrieve and set IP configuration parameters.  It should only be used in
     a test and debug context.  Using it for any other purpose is strongly
     discouraged.  Public API's in the SystemConfiguration framework are cur-
     rently the only supported way to access and control the state of IPCon-
     figuration.

     ...

     getifaddr interface-name
                 Prints to standard output the IP address for the first net-
                 work service associated with the given interface.  The output
                 will be empty if no service is currently configured or active
                 on the interface.

1

为了避免过多的管道,处理各种Linux系统,设置退出代码并避免使用ifconfig或其他包,我尝试在awk中完成整个操作:

 ip addr show | awk '
     BEGIN {FS="/"}
     /^[0-9]+: eth[0-9]+.*UP*/ {ss=1}
     ss==1 && /^ +inet / {print substr($1,10); exit 0}
     END {exit 1}'

请注意,如果您不只想要第一个eth接口,可以在“ip addr show”之后指定特定的接口。适应IPv6只需要寻找“inet6”而不是“inet”...

由于许多系统不再使用“eth *”命名接口,因此此操作现在失败了。(我的一台笔记本电脑上是“enp0s25”)它还完全忽略“ppp *”和其他类型的接口。 - Ian D. Allen

0
在我的情况下,在 eth0 之前,我的列表中有一些更多的接口。使用此命令,您可以获取任何接口的 ip4 地址。为此,您需要将 eth0 更改为您需要的接口。
/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'

0
如果你所说的“我的 IP 地址”是指“我连接到公共互联网时我的机器将使用的 IP 地址”,那么这个非常整洁的 JSON 答案可能适用于你,具体取决于你的机器运行的操作系统:
ip=$( ip -j route get 8.8.8.8 | jq -r '.[].prefsrc' )

这需要一个产生JSON输出的ip命令(有人说BusyBoxip命令无法做到这一点),CLI jq解析器可以从JSON输入中提取字段,而且您的计算机必须知道如何到达公共IP地址8.8.8.8。

如果您想要获取计算机访问其他地方(例如本地网络)时使用的IP地址,请将该其他IP地址放在公共IP 8.8.8.8的位置,例如:

ip=$( ip -j route get 192.168.1.1 | jq -r '.[].prefsrc' )
ip=$( ip -j route get 10.1.2.3    | jq -r '.[].prefsrc' )

如果您只有一个接口,则几乎任何非本地主机IP地址都可以用于获取您的IP地址。

使用jq解析JSON输出比所有那些复杂的sedawkgrep示例要简单得多,但更复杂的示例确实使用了几乎所有Unix/Linux/BSD系统默认提供的工具。


0
假设你有像curl或wget这样的东西,那么获取外部IP地址的一种简单方法而无需下游分析是:
- (wget的通配符语法可能不同)
curl -w '\n\n%{url_effective}\n\n' -s 'http://api{,6}.ipify.org' 
98.xxx.132.255

http://api.ipify.org/

2603:7000:xxxx:xxxx:xxxx:c80f:1351:390d

http://api6.ipify.org/

一次性返回IPv4IPv6地址


0

"eth3"是可选的(适用于多个网卡)

ipaddress=`ip addr show eth3 | grep 'inet ' | awk '{ print $2}' | cut -d'/' -f1`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接