【问题标题】:Putting IP Address into bash variable. Is there a better way将 IP 地址放入 bash 变量中。有没有更好的办法
【发布时间】:2011-07-26 11:54:05
【问题描述】:

我正在尝试找到一种简短而可靠的方法来将我的 IP 地址放入 bash 变量中,并且很好奇是否有更简单的方法可以做到这一点。这就是我目前的做法:

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

【问题讨论】:

  • 你是如何添加反引号的?
  • 如果你在行前放了4个空格,它被认为是代码,并且它们的反引号不会被处理

标签: bash


【解决方案1】:

我也一直在为此苦苦挣扎,直到我发现有一个用于此目的的简单命令

hostname -i

就这么简单!

【讨论】:

  • 这可能是最好的解决方案。
  • 在我的情况下,ip 无法解析,我必须将 ip 分配给 eth1 私有接口,所以我做了hostname -I | cut -f2 -d' '
  • 请注意,这在 OSX 上不起作用。唯一的 hostname 选项是 -fs
  • 实际上,除了 GNU 的 hostname 实现之外,所有hostname 提示/答案很可能会失败,就像几乎所有其他人一样,该工具旨在设置主机名而不是查找有趣的东西。据我所知,这包括 OSX、*BSD、Solaris 等等。
  • 我有多个IP!结果:192.168.0.77 192.168.2.77 192.168.1.77 172.17.0.1
【解决方案2】:

man hostname 建议使用--all-ip-addresses 标志(简写-I),而不是-i,因为-i 仅在可以解析主机名时才有效。所以这里是:

hostname  -I

如果你只对主要的感兴趣,cut它:

hostname  -I | cut -f1 -d' '

【讨论】:

  • 我从hostname -I: 192.168.1.30 获得的一台服务器,只有一个IP。在我的 VPS 服务器上,我得到了这个输出127.0.0.2 143.127.52.130 2a00:dee0:ed3:83:245:70:fc12:d196,所以我需要添加一些过滤器。在我的linux tuner -I` 上不存在,所以最好的是ip route get 8.8.8.8 | awk 'NR==1 {print $NF}'
  • 只有 Linux,没有 Mac,但这是最好的答案。
  • 请注意,-I 的手册页说 不要对输出的顺序做任何假设。
【解决方案3】:

ip 是正确的工具,因为ifconfig 已经被弃用了一段时间。这是一个 awk/sed/grep-free 命令,它比此处发布的任何其他命令都快得多!:

ip=$(ip -f inet -o addr show eth0|cut -d\  -f 7 | cut -d/ -f 1)

(是的,这是第一个 -d 之后的转义空格)

【讨论】:

    【解决方案4】:

    您可以查看this site 的替代方案。

    一种方法是:

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

    稍微小一点,虽然它一点也不健壮,并且可能会根据您的系统返回错误的值:

    $ /sbin/ifconfig | sed -n '2 p' | awk '{print $3}'
    

    (来自http://www.htmlstaff.org/ver.php?id=22346)

    【讨论】:

    • 我正在寻找一种更短或更简单的解决方案。但是感谢您提供的链接,我将对其进行检查。
    • 抱歉,但我认为没有更短(或通过管道使用更少程序)的替代方案......
    • @woliveirajr 在 Ubuntu 12.04 中它将是 awk | '{print $2}'。但是您更长的解决方案比这更具互操作性。
    • ifconfig 在 Linux 上早已被弃用(但不是在 BSD 上),并且自 2001 年以来一直没有更新!都应该使用iproute2命令来获取网络信息,比如ip a
    • 您可以使用ifconfig eth0 | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'获取特定接口的IP地址,例如本例中的eth0。
    【解决方案5】:

    ifdata 命令(在moreutils 包中找到)提供了一个接口,可以轻松检索 ifconfig 数据,而无需手动解析 ifconfig 的输出。只需一条命令即可实现:

    ifdata -pa eth1
    

    eth1 是您的网络接口的名称。

    我不知道这个包在没有安装 ifconfig 时的行为。正如Syncrho 在他的回答中所说,ifconfig 已经被弃用了一段时间,并且不再在许多现代发行版中找到。

    【讨论】:

    • 是的!这应该是正确的答案。非常感谢您展示了这个出色且急需的实用程序。
    【解决方案6】:

    这是将设备的 IP 地址放入变量的最佳方法:

    ip=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')
    

    NB 更新以支持新的 Linux 版本。 (也适用于老年人)

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

    为什么是最好的?

    1. Hostname -I 有时只获得 IP 或在我的 VPS 上获得 127.0.0.2 143.127.52.130 2a00:dee0:ed3:83:245:70:fc12:d196
    2. Hostnmae -I 不适用于所有系统。
    3. 使用ifconfig 可能并不总是提供您喜欢的IP。
      一种。如果您有多个接口(wifi/etcernet)等,它将失败。
      湾。主 IP 可能不在第一个找到的接口上
    4. 如果接口在VPS 服务器或wifi 中具有其他名称,则搜索eth0 可能会失败

      ip路由得到8.8.8.8

    尝试获取到 Google 的 DNS 服务器的路由和接口(不打开任何会话)
    然后很容易得到ip 或者你喜欢的接口名称。

    这也可用于获取多路由网络上主机接口的ip 地址

    【讨论】:

    • 所以我猜如果在将 Google 的 DNS 服务器连接到互联网的路由器上运行它会失败... :)
    • @user000001 那将是大约 1 到 1000000000 的机会 :)
    【解决方案7】:

    我的简短版本。当您有多个接口并且只想要主 IP 时很有用。

    host `hostname` | awk '{print $4}'
    

    【讨论】:

    • 使用print $NF(最后一个字段)而不是print $4可能会更健壮。
    【解决方案8】:

    你可以只用 awk 来完成 ifconfig 的所有解析:

    ip=$(ifconfig | gawk '
        /^[a-z]/ {interface = $1}
        interface == "eth0" && match($0, /^.*inet addr:([.0-9]+)/, a) {
            print a[1]
            exit
        }
    ')
    

    【讨论】:

      【解决方案9】:

      不是真的更短或更简单,但它对我有用:

      ip=$(ip addr show eth0 | grep -o 'inet [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o [0-9].*)
      

      【讨论】:

        【解决方案10】:

        以下适用于 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}');
        

        【讨论】:

          【解决方案11】:

          我正在使用

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

          这种方式的优点是指定接口(示例中为变量IFACE),以防您在主机上使用多个接口。

          此外,您可以修改 ip command 以便在您方便的时候调整这个 sn-p(IPv6 地址等)。

          【讨论】:

            【解决方案12】:

            我认为最可靠的答案是:

            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 时,它会显示所有 ips....

            【讨论】:

              【解决方案13】:

              在我的脚本中,我确实只需要 IP 的网络部分,所以我就这样做了

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

              在哪里切 -f1,2,3 -d"。"可以读作“获取前 3 部分用逗号分隔” 要更改接口,只需将 $2 更改为您的接口编号,即可删除整个 IP。

              【讨论】:

                【解决方案14】:
                ifconfig | grep -oP "(?<=inet addr:).*?(?=  Bcast)"
                

                当使用 grep 提取一行的一部分时(就像其他一些答案一样),perl 前瞻和后瞻断言是你的朋友。

                快速解释是第一个(?&lt;=inet addr:) 和最后一个(?= Bcast) 括号包含必须匹配的模式,但是grep 不会返回匹配这些模式的字符,只有之间的字符返回两个模式并匹配括号集之间的模式.*?。

                ifconfig 输出示例:

                eth0      Link encap:Ethernet  HWaddr d0:67:e5:3f:b7:d3  
                          inet addr:10.0.0.114  Bcast:10.0.0.255  Mask:255.255.255.0
                          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                          RX packets:1392392 errors:0 dropped:0 overruns:0 frame:0
                          TX packets:1197193 errors:0 dropped:0 overruns:0 carrier:0
                          collisions:0 txqueuelen:1000 
                          RX bytes:1294730881 (1.2 GB)  TX bytes:167208753 (167.2 MB)
                          Interrupt:18
                

                这将从 ifconfig 输出中提取您的 IP 地址:

                ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)"
                

                要将其分配给变量,请使用:

                ip=$(ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)")
                

                稍微深入一点的解释:

                来自 man grep:

                -o 只打印匹配行的匹配(非空)部分,每个这样的部分在单独的输出行上。

                -P 将模式解释为 Perl 正则表达式。这是高度实验性的,“grep -P”可能会警告未实现的功能。

                来自permonks.org:

                (?&lt;=pattern) 是一个积极的后视断言

                (?=pattern) 是一个积极的前瞻断言

                -o 告诉 grep 只返回与模式匹配的行部分。 grep 不认为后视/前瞻是返回的模式的一部分。 .* 之后的 ? 很重要,因为我们希望它在 .* 模式匹配后寻找下一个前瞻,而不是寻找最后一个前瞻匹配。 (如果我们为 IP 地址添加正则表达式而不是 .*,则不需要这样做,但是,可读性)。

                【讨论】:

                  【解决方案15】:

                  为了避免过多的管道、在各种 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”...

                  【讨论】:

                    【解决方案16】:

                    就我而言,eth0 之前的列表中有更多接口。通过此命令,您可以获得任何接口的 ip4 地址。为此,您需要将eth0 更改为您需要的接口。

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

                    【讨论】:

                      【解决方案17】:

                      “eth3”是可选的(对多个网卡有用)

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

                      【讨论】:

                        【解决方案18】:

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

                        【讨论】:

                          猜你喜欢
                          • 2021-12-28
                          • 1970-01-01
                          • 2016-02-21
                          • 2012-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2022-01-22
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多