【问题标题】:Parse ifconfig to get only my IP address using Bash使用 Bash 解析 ifconfig 以仅获取我的 IP 地址
【发布时间】:2014-07-19 00:32:55
【问题描述】:

我想编辑 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。

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

【问题讨论】:

  • 哪个操作系统?哪个 ifconfig?
  • ifconfig en1 | sed -n '/inet addr/s/.*addr.\([^ ]*\) .*/\1/p' 至少在 ubuntu、fedora 上工作...根据您的 ifconfig en1 输出,您可以根据需要进行更多调整。
  • /sbin/ifconfig $1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'。定义位置,因为它在用户PATH 中通常不存在,root 除外

标签: macos bash awk ifconfig


【解决方案1】:

无需在 Bash 中进行不可移植的 ifconfig 解析。这是 Python 中的一个微不足道的单行代码:

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

【讨论】:

  • 它可以在我连接到廉价家庭互联网连接的笔记本电脑上运行。 gethostname() 对我来说返回 myclevername.local,正如你所看到的,这不是真正的 DNS,除了连接到 Wi-Fi 之外我没有设置任何东西。
  • 您的路由器/等。很可能正在为从中获得 DHCP 租约的设备做某种动态 DNS。尝试在该地址上使用hostdig,看看你得到了什么(以及从谁那里)。
  • 我得到 NXDOMAIN(未找到)。然而 Python 代码运行良好。我同意可能存在 Python 代码会失败的“特殊配置”主机,但我认为它们并不常见。
  • 您的/etc/hosts 文件中是否有该域的非本地主机条目?
  • 为我工作,但这个解决方案是 Pythonic 的,而我希望得到一个 Bash'ish 的答案。
【解决方案2】:

以下两个都可以在这里工作(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}'

【讨论】:

  • 我不想质疑你的回答,但我使用的是 Mac OSX。不过还是谢谢。
  • @FernandoRetimo 在 OS X 上 ifconfigip 的原始输出是什么?
  • ifconfig 在 CentOS 7 上对我不起作用。但 ip addrone 对我有用。谢谢。
  • @TyagiAkhilesh ifconfig 已被弃用(并且已经存在很长时间了)并且 CentOS 7 不再默认提供它。
  • 运行一个命令来解析它的输出而不强制语言环境就像在你的脚上开了一枪。使用LC_ALL=C ifconfig 而不仅仅是ifconfig
【解决方案3】:

在 eth0 的情况下,以下对我有用。尝试用相同的逻辑对其进行调整。

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

【讨论】:

  • 因为我害怕 awk,所以我有一个稍微不同的版本:ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1
  • 在 Mac OSX 上不工作...原因是 ifconfig 的语法有点不同。不过还是谢谢。
  • so上有一个类似的帖子。希望这可以帮助! stackoverflow.com/questions/7181998/…
【解决方案4】:

好吧,经过几个小时的努力,我终于弄对了:

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

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

【讨论】:

  • 这也会为你完成:ifconfig en1|awk '/inet / {print $2}'
  • 我认为这不是最佳选择,因为它推断您总是知道该设备。如果它发生变化等,您将收到错误“获取接口信息时出错:未找到设备”
【解决方案5】:

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

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

在上面的示例中,将设备句柄 eth0 替换为 docker0。另外,如果你想要一个纯粹的 AWK 实现,你可以像这样在里面进行“切割”:

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

【讨论】:

    【解决方案6】:

    如果您只是在寻找“inet”而不是“inet6”,这对我有用:

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

    "--word-regexp" 将使 grep 查找整个单词 "inet" 而不是匹配部分单词,即 "inet" 不会匹配 "inet6" - "inet" 只会匹配带有 "inet" 的行"在他们里面。

    【讨论】:

      【解决方案7】:

      类似于 JSR,但 awkcut 顺序相反:

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          也适用于 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 ' '
          

          【讨论】:

            【解决方案10】:
            ifconfig eth0 | awk '/inet addr/{sub("addr:",""); print $2}'
            

            【讨论】:

            • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
            【解决方案11】:

            采用patch的答案,使其更笼统,

            即:跳过所有内容直到第一个数字。

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

            甚至更好:

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

            • 请注意末尾的 print 部分 - 从 $2 更改为 $1

            使用 Perl 正则表达式:

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

            解释:grep -oP 使用 Perl 正则表达式搜索精确匹配。
            “棘手”的部分是正则表达式本身;
            1. (?&lt;= inet addr:) 表示 - 字符串 inet addr: 位于我们要查找的内容的左侧。
            2. [^ ]+(请注意 ^ 后面的空格) - 这意味着查找所有内容,直到第一个空白 - 在我们的例子中是 IP 地址。

            【讨论】:

              【解决方案12】:

              用途:

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

              enops3 是接口名称。

              【讨论】:

              • 注意应该是 grep 而不是 greb(会编辑答案,但说队列已满)。
              【解决方案13】:

              除了解析 ifconfig 之外,还有另一种简单的方法来获取 IP 地址。

              hostname -I -I, --all-ip-addresses all addresses for the host -i, --ip-address addresses for the hostname

              参考:http://linux.die.net/man/1/hostname

              示例:

              [ec2-user@terraform ~]$ 主机名 -I
              10.10.10.10

              【讨论】:

                【解决方案14】:

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

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

                • 活动的网络适配器未知,
                • 在 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 的结果 - 所以它是为了便携性而保留的。

                【讨论】:

                  【解决方案15】:

                  一个简单的 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 ""
                          }
                      }
                  }'
                  

                  【讨论】:

                  • 天哪,你没看到另一个班轮回答吗?
                  • 不错的脚本,但你的只是将它们全部显示出来,实际上与使用 ifconfig 没有什么不同 .. 对脚本中的应用程序没有用...
                  【解决方案16】:

                  使用 BASH4+ 的 IPv4 示例

                  示例 1,使用主机名:

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

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

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

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

                   ip a | awk 'BEGIN{ "hostname -I|cut -d\" \" -f 1" | getline ip} $2 ~ ip {print "Device: "$NF "  IP: "$2}'
                  

                  示例4,要网络IP地址:

                   wget -q -O /dev/stdout http://checkip.dyndns.org/ | cut -d":" -f2 | cut -d \< -f1
                  

                  享受吧。

                  【讨论】:

                    【解决方案17】:

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

                    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

                    【讨论】:

                      【解决方案18】:

                      这是获取 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,请将 | 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 ...

                      最后,您注意到脚本所做的其中一件事是省略了由系统管理员和开发人员“localhost”调用的 IP 127.0.0.1,但考虑到某些应用程序还可能添加具有 IP 的虚拟网络设备可能如果没有添加到省略列表中,则返回一个,例如。 Docker 添加了一个虚拟接口docker0,它通常具有 IP 172.17.0.1,如果您想省略这个 IP 以及“localhost”,请更改表达式grep -v 127.0.0.1 以考虑另一个 IP。在这种情况下(省略 localhost 和 docker),最终表达式将是:

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

                      以下是本页中提到的一些在某些情况下失败的示例以及原因:

                      • ip route ...ip 命令未安装在 OSX 机器中。
                      • 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 发行版中不起作用,因为 grep 查找的文本 inet addr: 在其他语言环境中以不同的文本输出,并且在 Mac OS 中,该标签也不同。

                      【讨论】:

                      • 那个答案给我当场
                      【解决方案19】:

                      你也可以试试这个

                      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:~$
                      

                      【讨论】:

                        【解决方案20】:

                        在遇到 greping ifconfig 的麻烦后,我找到了一个包装库来简化我的生活

                        pip install my_ip 
                        mip
                        

                        【讨论】:

                        • ifconfig 现在不使用了。相反,我们有ip
                        猜你喜欢
                        • 2015-01-22
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-10-05
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-06-02
                        • 1970-01-01
                        相关资源
                        最近更新 更多