解析ifconfig只使用Bash获取我的IP地址

时间:2014-05-29 13:23:10

标签: macos bash awk ifconfig

我想编辑bashrc文件,以便运行一个名为“myip”的简单函数。正如您可能猜到的,myip函数仅打印我机器的内部IP地址。

就在我工作的时候,这是剧本:

ifconfig en1 | awk '{ print $2}' | sort

我得到了这个输出:

10.0.0.12
options=1<PERFORMNUD>
flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST>
fe80::daa2:5eff:fe96:ba2f%en1
d8:a2:5e:96:ba:2f
autoselect
active

我正在使用Mac OS X.

我怎样才能完成这项工作?

19 个答案:

答案 0 :(得分:23)

以下两项工作(CentOS 5)。

ip addr show eth0 | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}'

ifconfig eth0 | awk '/inet addr/ {gsub("addr:", "", $2); print $2}'

对于OS X(至少v10.11(El Capitan)):

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

答案 1 :(得分:15)

这是获取IP地址的更多“不可知”方式,无论您使用* nix系统(Mac OS,Linux),接口名称,甚至您的语言环境配置:

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d:

如果您有多个活动IP,则会将每个活动IP列在一个单独的行中。如果您只想要第一个IP,请将| head -n1添加到表达式:

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" \
     | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

如果您想要特定接口的IP地址,请将第一个表达式ifconfig替换为ifconfig INTERFACENAME,例如ifconfig eth0 | grep -E ...

本页提到的一些示例在某些情况下失败,原因如下:

  • ip route ...:OSX计算机中未安装ip命令。
  • hostname -I-I选项在OSX中无效。
  • ifconfig en0 ...:接口名称(eth0en0)在Linux和OSX中不同,在Linux中,名称也取决于接口类型( ethX 用于以太网连接, wlanX 用于无线等)。
  • python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))':这让我在Ubuntu Linux 14.04中获得127.0.1.1环回IP ),因此无效。
  • ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' ':Geograph的帖子越接近,但在没有配置LANG=en的某些Linux发行版中不起作用,因为inet addr:寻找的文字grep在其他语言环境中输出不同的文本,在Mac OS中,标签也不同。

答案 2 :(得分:12)

如果是eth0,以下内容适用于我。尝试用相同的逻辑调整它。

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

答案 3 :(得分:8)

好吧,经过几个小时的挣扎,我终于做对了:

ifconfig en1 | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"

我遗漏的最后一部分只是从我的列表中看到一个IP地址模式。

答案 4 :(得分:7)

您可以使用awk同时选择inet行和解析IP地址,如下所示:

$ ip addr ls docker0 | awk '/inet / {print $2}' | cut -d"/" -f1
172.17.42.1

在上面的示例中,将设备句柄eth0替换为docker0。此外,如果您想要一个纯AWK实现,您可以执行&#34; cut&#34;像这样:

$ ip addr ls docker0 | awk '/inet / {split($2, ary, /\//); print ary[1]}'
172.17.42.1

答案 5 :(得分:3)

使用BASH4 +的示例

示例1 ,使用主机名:

.validate()

示例2,设备已知(并且永远不会更改):

.validate()

示例3 ,现在不要使用设备(例如eth0,eth1,enp0s23或wpxxx):

  hostname -I|cut -d" " -f 1

示例4 ,需要网络IP地址:

  ifconfig ens5 | grep "inet" | awk '{print $2}' |  sed 's/[^0-9.]*//g'

享受。

答案 6 :(得分:2)

无需在Bash中进行不可移植的ifconfig解析。它在Python中是一个简单的单行程序:

python -c 'import socket; print(socket.gethostbyname(socket.gethostname()))'

答案 7 :(得分:2)

你也可以尝试这个

user@linux:~$ cat script.sh
ifconfig | grep ad.*Bc | cut -d: -f2 | awk '{ print $1}'
user@linux:~$ 

输出

user@linux:~$ ./script.sh
192.168.1.1
10.0.1.1
user@linux:~$

请注意ifconfig输出可能因您的linux版本而异。因此,您可能希望相应地更改脚本。

顺便说一句,这是我的ifconfig输出

user@linux:~$ ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:00:00:00:00:10  
          inet addr:192.168.1.1  Bcast:192.168.56.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:112 errors:0 dropped:0 overruns:0 frame:0
          TX packets:93 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:14616 (14.2 KiB)  TX bytes:17776 (17.3 KiB)

eth1      Link encap:Ethernet  HWaddr 00:00:00:00:00:11
          inet addr:10.0.1.1  Bcast:10.0.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

user@linux:~$

答案 8 :(得分:1)

如果您正在寻找&#34; inet&#34;而不是&#34; inet6&#34;,这对我有用:

/usr/bin/ifconfig eth0 | grep --word-regexp inet | awk '{print $2}'

&#34; - 字的正则表达式&#34;会让grep找到整个单词&#34; inet&#34;并且不匹配单词的部分,即&#34; inet&#34;赢得了比赛&#34; inet6&#34; - &#34; inet&#34;只会匹配&#34; inet&#34;在他们中间。

答案 9 :(得分:0)

遇到麻烦xcrun simctl privacy booted reset location <your_app_bundle_id>之后,我找到了一个包装器库来简化我的生活

ifconfig

答案 10 :(得分:0)

在尝试了一些解决方案后,我发现这个最方便, 将此添加到您的别名:

alias iconfig='ifconfig | awk '\''{if ( $1 >= "en" && $2 >= "flags" && $3 == "mtu") {print $1}; if ( $1 == "inet" || $1 == "status:"){print $0};}'\''|egrep "en|lo|inet"'

输出如下:

shady@Shadys-MacBook-Pro:xxxx/xxx ‹dev*›$ iconfig lo0: inet 127.0.0.1 netmask 0xff000000 en0: inet 10.16.27.115 netmask 0xffffff00 broadcast 10.16.27.255 en1: en2: en5: inet 192.168.2.196 netmask 0xffffff00 broadcast 192.168.2.255

答案 11 :(得分:0)

此代码输出所有网络连接的IP地址(环回除外),并且可在大多数 OS X和Linux版本之间移植。

对于在以下机器上运行的脚本特别有用:

  • 活动网络适配器未知,
  • 在Wi-Fi和以太网连接之间切换的笔记本电脑和
  • 具有多个网络连接的计算机。

脚本是:

/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2

这可以分配给脚本中的变量,如下所示:

myip=$(/sbin/ifconfig -a | awk '/(cast)/ {print $2}' | cut -d: -f2)

脚本可以通过使用循环来处理结果来处理可能的多个地址,如下所示:

if [[ -n $myip ]]; then
  count=0
  for i in $myip; do
    myips[count]=$i       # Or process as desired
    ((++count))
  done
  numIPaddresses=$count   # Optional parameter, if wanted
fi

注意:

  • 它会过滤“cast”上的“ifconfig”,因为这样可以过滤掉环回地址,同时还可以处理大多数OS X和Linux版本。
  • 最终的'cut'功能对于Linux上的正常功能是必需的,但不是OS X.但是,它不会影响OS X的结果 - 所以它留给了便携性。

答案 12 :(得分:0)

使用:

ifconfig enops3 | greb broadcast | cut -d " " -f10

其中enops3是接口名称。

答案 13 :(得分:0)

采取补丁答案,使其更加通用,

即:跳过一切直到第一个数字。

ifconfig eth0 | awk '/inet addr/{sub(/[^0-9]*/,""); print $1}'

甚至更好:

ifconfig eth0 | awk '/inet /{sub(/[^0-9]*/,""); print $1}'

  • 请注意最后的打印部分 - 从 $ 2 更改为 $ 1

使用Perl Regex:

ifconfig eth0 | grep -oP '(?<= inet addr:)[^ ]+'

说明:grep -oP使用Perl正则表达式搜索精确匹配 “棘手”部分是正则表达式本身;
1. (?<= inet addr:)表示 - 字符串inet addr:是我们正在寻找的左边。
2. [^ ]+(请注意^之后的空格) - 它意味着在第一个空白之前查找所有内容 - 在我们的例子中它是IP地址。

答案 14 :(得分:0)

代码也适用于VDS / VPS:

ifconfig | grep -A2 "venet0:0\|eth0" | grep 'inet addr:' | sed -r 's/.*inet addr:([^ ]+).*/\1/' | head -1

ifconfig | grep 'inet addr:' | grep -v 127.0.0.1 | head -n1 | cut -f2 -d: | cut -f1 -d ' '

答案 15 :(得分:0)

这对我有用:
ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

答案 16 :(得分:0)

与JSR类似,但awkcut的顺序相反:

my_ip=$(ifconfig en1 | grep 'inet addr' | awk '{print $2}' | cut -d: -f 2)
echo ${my_ip}

答案 17 :(得分:-1)

一个简单的AWK + Bash脚本示例,它可以概括地说明如何解析命令输出并将语法混合在一起。

完整代码位于:https://gist.github.com/darkphase/67d7ec22d47dbebd329e

BEGIN { RS = "" ; FS = "\n" }  # Change separator characters
{
    while ( "'"$cmd"'" | getline ){
        # print $0
        if ( $1 !~ /LOOPBACK/ ){

            split($1,arr," ")
            print "'"$blue"'"arr[1]"'"$reset"'"

            for(i = 1; i <= NF; i++) { # Loop through fields (this case lines)
                split($i,arr," ")
                switch ( arr[1] ) {
                    case "inet":
                        print "'"$red"'" "IPV4:" "'"$reset"'" "\n IP: " "'"$yellow"'" arr[2] "'"$reset"'" "\n NM: "arr[4]"\n BC: "arr[6]
                        break
                    case "inet6":
                        print "'"$red"'" "IPV6:" "'"$reset"'" "\n IP: "arr[2]"\n PL: "arr[4]
                        break
                    case "ether":
                        print "'"$red"'" "MAC: " "'"$reset"'" arr[2]
                        break
                    default:
                }
            }
            print ""
        }
    }
}'

答案 18 :(得分:-1)

main