如何在Linux和OS X上获取本地计算机的主IP地址?

sor*_*rin 318 unix ip bash ifconfig

我正在寻找一个命令行解决方案,它将返回localhost的主(第一)IP地址,而不是127.0.0.1

该解决方案至少适用于Linux(Debian和RedHat)和OS X 10.7+

我知道ifconfig两者都可用,但它们的输出在这些平台之间并不一致.

Chr*_*our 454

使用grep从过滤IP地址ifconfig:

ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'

或者sed:

ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'

如果您只对某些接口,wlan0,eth0等感兴趣,那么:

ifconfig wlan0 | ...

您可以在命令中使用别名.bashrc创建自己的命令myip,例如.

alias myip="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'"

一种更简单的方法是hostname -I(hostname -i对于旧版本,hostname但请参阅注释).但是,这仅适用于Linux.

  • OSX:ipconfig getifaddr en0 (12认同)
  • 另请注意,在OSX中,sed对扩展RE使用`-E`选项,而不是GNU样式的`-r`选项. (5认同)
  • 我发现了一个问题,虽然这适用于 OS X,但它确实返回了多个 IP,即 IP 列表。似乎第一个是正确的,但这仍然会打破我的逻辑。请参阅 https://gist.github.com/ssbarnea/31b9dcb0f8fd528b958c - 它还返回活动但由并行使用的 vnic 。 (2认同)

ACy*_*lic 218

对于linux机器(不是OS X):

hostname --ip-address
Run Code Online (Sandbox Code Playgroud)

  • 这有时只返回127.0.0.1.如果可用,最好按照手册(Ubuntu)的建议使用**hostname -I**:_" - ip-address显示主机名的网络地址.请注意,这仅适用于主机名可以要避免使用此选项;请改用hostname --all-ip-addresses."_ (71认同)
  • `hostname -i`是等效的简写形式 (35认同)
  • 仅当名称在DNS中时才有效.如果没有,则会收到消息"主机名:名称或服务未知". (9认同)
  • 在我的机器上,“主机名-i”仅给出本地IP,而“主机名-I`给出所有其他IP。 (2认同)
  • 这在我的机器上返回 127.0.0.1 (2认同)

Col*_*son 215

以下内容适用于Linux,但不适用于OSX.

这根本不依赖于DNS,即使/etc/hosts没有正确设置它也是有效的(1是简写1.0.0.0):

ip route get 1 | awk '{print $NF;exit}'
Run Code Online (Sandbox Code Playgroud)

或明显避免awk和使用谷歌的公共DNS 8.8.8.8:

ip route get 8.8.8.8 | head -1 | cut -d' ' -f8
Run Code Online (Sandbox Code Playgroud)

一种不太可靠的方式:(见下面的评论)

hostname -I | cut -d' ' -f1
Run Code Online (Sandbox Code Playgroud)

  • **这**(第一个)**是唯一正确的解决方案**.从与默认路由关联的接口专门读取IP是非常重要的.否则你很可能得到一些毫无价值的内部地址. (11认同)
  • 它对我不起作用,但它足够封闭:`ip route get 1 | sed -n's /^.*src \([0-9.]*\).*$ /\1/p'` (11认同)
  • 对我来说,`ip route get 1 | awk'{print $(NF-2); exit}'`当我将uid附加到outptut时起作用 (9认同)
  • 获取由`hostname -I`生成的第一个地址的方法是不可靠的,因为(根据文档),人们不能对地址的顺序做出任何假设.所以它可能是一些内部网络(如虚拟机所在的网络).另一种方法似乎很好. (8认同)
  • 这应该是公认的答案,因为RHEL 7不再包含ifconfig. (3认同)
  • 请注意,这些都不适用于OS X. (3认同)
  • 请注意`ip route get 8.8.8.8 | 头-1 | cut -d' ' -f8` 不适用于本地网络 IP,仅适用于远程 IP,因为“ip Route get”的输出与那时不同(缺少“via 192.168.1.1”部分)。然后您需要将“-f8”更改为“-f6”。或者简单地使用“awk”解决方案,它在所有这些情况下对我来说都是可靠的。 (2认同)
  • @estani 的解决方案适用于新的 `ip` 输出(附加“uid xxxx”)和旧的 `ip` 输出。 (2认同)
  • 好像 ip 的输出格式不太稳定。对我来说,`cut -d' ' -f8` 不起作用,但 `cut -d' ' -f7` 起作用。 (2认同)
  • 我认为`iproute get 1 | awk '{gsub("^.*src",""); 打印 1 美元;exit}'` 更好 - ip 路由有太多不同的变体,这些变体在那条线上有不同的东西。这会查找与“src”一起的 IP 并打印它。 (2认同)

F. *_*uri 34

编辑(2014-06-01 2018-01-09)

对于更强的配置,在每个接口上配置了许多接口和许多IP,我编写了一个纯bash脚本(不是基于127.0.0.1),用于查找正确的接口 ip,基于default route.我在这个答案的最底部发布了这个脚本.

介绍

由于两个操作系统都默认安装的,没有为Mac和Linux是bash提示:

使用以下方法阻止了区域设置问题LANG=C:

myip=
while IFS=$': \t' read -a line ;do
    [ -z "${line%inet}" ] && ip=${line[${#line[1]}>4?1:2]} &&
        [ "${ip#127.0.0.1}" ] && myip=$ip
  done< <(LANG=C /sbin/ifconfig)
echo $myip
Run Code Online (Sandbox Code Playgroud)

把它放到一个函数中:

最小:

getMyIP() {
    local _ip _line
    while IFS=$': \t' read -a _line ;do
        [ -z "${_line%inet}" ] &&
           _ip=${_line[${#_line[1]}>4?1:2]} &&
           [ "${_ip#127.0.0.1}" ] && echo $_ip && return 0
      done< <(LANG=C /sbin/ifconfig)
}
Run Code Online (Sandbox Code Playgroud)

使用简单:

getMyIP
192.168.1.37
Run Code Online (Sandbox Code Playgroud)

花哨整洁:

getMyIP() {
    local _ip _myip _line _nl=$'\n'
    while IFS=$': \t' read -a _line ;do
        [ -z "${_line%inet}" ] &&
           _ip=${_line[${#_line[1]}>4?1:2]} &&
           [ "${_ip#127.0.0.1}" ] && _myip=$_ip
      done< <(LANG=C /sbin/ifconfig)
    printf ${1+-v} $1 "%s${_nl:0:$[${#1}>0?0:1]}" $_myip
}
Run Code Online (Sandbox Code Playgroud)

用法:

getMyIP
192.168.1.37
Run Code Online (Sandbox Code Playgroud)

或者,运行相同的函数,但带有一个参数:

getMyIP varHostIP
echo $varHostIP
192.168.1.37
set | grep ^varHostIP
varHostIP=192.168.1.37
Run Code Online (Sandbox Code Playgroud)

Nota:没有参数,这个函数在STDOUT上输出,IP和换行符,带参数,没有打印,但是创建了一个名为参数的变量,包含没有换行符的 IP .

Nota2:这是在Debian上测试的,LaCie攻击了nas和MaxOs.如果这在你的环境下不起作用,我会对反馈非常感兴趣!

这个答案的旧版本

(不删除因为基于sed,而不是bash.)

警告:有关于语言环境的问题!

快速和小:

myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}')
Run Code Online (Sandbox Code Playgroud)

爆炸(也是工作;)

myIP=$(
    ip a s |
    sed -ne '
        /127.0.0.1/!{
            s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p
        }
    '
)
Run Code Online (Sandbox Code Playgroud)

编辑:

怎么样!这似乎不适用于Mac OS ...

好吧,这在Mac OS和我的Linux上看起来完全相同:

myIP=$(LANG=C /sbin/ifconfig  | sed -ne $'/127.0.0.1/ ! { s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p; }')
Run Code Online (Sandbox Code Playgroud)

分裂:

myIP=$(
    LANG=C /sbin/ifconfig  |
        sed -ne $'/127.0.0.1/ ! {
            s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p;
        }')
Run Code Online (Sandbox Code Playgroud)

我的剧本(2018年1月):

此脚本将首先找到您使用的默认路由接口,然后搜索本地IP匹配网关网络并填充变量.最后两行只是打印,如:

Interface   : en0
Local Ip    : 10.2.5.3
Gateway     : 10.2.4.204
Net mask    : 255.255.252.0
Run on mac  : true
Run Code Online (Sandbox Code Playgroud)

要么

Interface   : eth2
Local Ip    : 192.168.1.31
Gateway     : 192.168.1.1
Net mask    : 255.255.255.0
Run on mac  : false
Run Code Online (Sandbox Code Playgroud)

嗯,它是:

#!/bin/bash
runOnMac=false
int2ip() { printf ${2+-v} $2 "%d.%d.%d.%d" \
        $(($1>>24)) $(($1>>16&255)) $(($1>>8&255)) $(($1&255)) ;}
ip2int() { local _a=(${1//./ }) ; printf ${2+-v} $2 "%u" $(( _a<<24 |
                  ${_a[1]} << 16 | ${_a[2]} << 8 | ${_a[3]} )) ;}
while IFS=$' :\t\r\n' read a b c d; do
    [ "$a" = "usage" ] && [ "$b" = "route" ] && runOnMac=true
    if $runOnMac ;then
        case $a in 
            gateway )    gWay=$b  ;;
            interface )  iFace=$b ;;
        esac
    else
        [ "$a" = "0.0.0.0" ] && [ "$c" = "$a" ] && iFace=${d##* } gWay=$b
    fi
done < <(/sbin/route -n 2>&1 || /sbin/route -n get 0.0.0.0/0)
ip2int $gWay gw
while read lhs rhs; do
    [ "$lhs" ] && { 
        [ -z "${lhs#*:}" ] && iface=${lhs%:}
        [ "$lhs" = "inet" ] && [ "$iface" = "$iFace" ] && {
            mask=${rhs#*netmask }
            mask=${mask%% *}
            [ "$mask" ] && [ -z "${mask%0x*}" ] &&
                printf -v mask %u $mask ||
                ip2int $mask mask
            ip2int ${rhs%% *} ip
            (( ( ip & mask ) == ( gw & mask ) )) &&
                int2ip $ip myIp && int2ip $mask netMask
        }
    }
done < <(/sbin/ifconfig)
printf "%-12s: %s\n" Interface $iFace Local\ Ip $myIp \
       Gateway $gWay Net\ mask $netMask Run\ on\ mac $runOnMac
Run Code Online (Sandbox Code Playgroud)


Bor*_*ris 34

在linux上

hostname -I
Run Code Online (Sandbox Code Playgroud)

在macOS上

ipconfig getifaddr en0
Run Code Online (Sandbox Code Playgroud)

请注意,hostname -I可以以不可靠的顺序返回多个地址(请参阅参考资料hostname).但对我来说,它只是回归192.168.1.X你想要的.

  • 对我来说,它是带有较低 I 的 `hostname -i`。 (2认同)
  • @PaulWoitaschek 小写“-i”标志的联机帮助页是这样说的:“避免使用此选项;使用主机名 -I 代替`。 (2认同)

gio*_*mhz 31

$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'
192.168.8.16
Run Code Online (Sandbox Code Playgroud)

说明

查询网络信息的正确方法是使用ip:

  • -o 单行输出
  • route get to 获取到目的地的实际内核路由
  • 8.8.8.8 Google IP,但可以使用您想要覆盖的真实IP

例如ip输出:

8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \   cache
Run Code Online (Sandbox Code Playgroud)

提取srcip,sed是最正确,最兼容的正则表达式支持:

  • -n 默认情况下没有输出
  • 's/pattern/replacement/p' 仅匹配图案和打印更换
  • .*src \([0-9.]\+\).* 匹配内核使用的src IP,以达到 8.8.8.8

例如最终输出:

192.168.8.16
Run Code Online (Sandbox Code Playgroud)

其他答案

我认为前面的答案对我来说都不够好,因为它们在最近的机器中不起作用(Gentoo 2018).

我在前面的答案中找到的问题:

  • 在命令输出中使用位置列;
  • 使用ifconfig不推荐使用 - 例如 - 不列出多个IP;
  • 使用awksed可以更好地处理的简单任务;
  • ip route get 1 目前还不清楚,实际上是别名 ip route get to 1.0.0.0
  • 使用hostname命令,-I在所有设备中没有选项,127.0.0.1在我的情况下返回.


小智 22

您也可以试试这个,虽然它可能会告诉您127.0.0.1:

hostname  -i
Run Code Online (Sandbox Code Playgroud)

要么

hostname -I
Run Code Online (Sandbox Code Playgroud)

  • 没有. - 它可能会告诉你127.0.0.1. (6认同)
  • `$ hostname --ip-address` 在 Arch Linux 上只给了我 `127.0.0.1` (2认同)
  • 使用主机名-I或主机名--all-ip-addresses (2认同)

Sat*_*ish 22

您还可以在linux中使用此命令获取eth0的IP版本4地址

/sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
Run Code Online (Sandbox Code Playgroud)

输出将是这样的

[root@localhost Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
192.168.1.22
Run Code Online (Sandbox Code Playgroud)


小智 14

这适用于Linux和OSX

这将获得与默认路由关联的接口

NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}'`
Run Code Online (Sandbox Code Playgroud)

使用上面发现的接口,获取IP地址.

NET_IP=`ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'`
Run Code Online (Sandbox Code Playgroud)

OSX

uname -a
Run Code Online (Sandbox Code Playgroud)

Darwin笔记本电脑14.4.0 Darwin内核版本14.4.0:2015年5月28日星期四11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_64

echo $NET_IF
Run Code Online (Sandbox Code Playgroud)

EN5

echo $NET_IP
Run Code Online (Sandbox Code Playgroud)

192.168.0.130

CentOS Linux

uname -a
Run Code Online (Sandbox Code Playgroud)

Linux dev-cil.medfx.local 2.6.18-164.el5xen 1 SMP Thu Sep 3 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

echo $NET_IF
Run Code Online (Sandbox Code Playgroud)

为eth0

echo $NET_IP
Run Code Online (Sandbox Code Playgroud)

192.168.46.10


Kje*_*rup 12

使用某些其他方法您可能会输入在系统上定义多个IP地址的冲突.默认情况下,此行始终获取IP地址.

ip route get 8.8.8.8 | head -1 | awk '{print $7}'
Run Code Online (Sandbox Code Playgroud)


Fai*_*oor 7

ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)


Put*_*nik 6

假设您需要从世界其他地方看到的主要公共IP,请尝试以下任一方法:

wget http://ipecho.net/plain -O - -q
curl http://icanhazip.com
curl http://ifconfig.me/ip
Run Code Online (Sandbox Code Playgroud)


小智 6

我必须向Collin Andersons回答,如果您有两个接口并且它们都显示为向上,则此方法也要考虑在内。

ip route get 1 | awk '{print $NF;exit}'
Run Code Online (Sandbox Code Playgroud)

我一直在与Raspberry Pi一起开发应用程序,并且需要实际使用的IP地址,而不仅仅是它是否已启动。其他大多数答案都将返回两个IP地址,这不一定有帮助-无论如何对于我的情况。


est*_*ani 6

我把我的评论提取到这个答案:

ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

它基于@CollinAnderson的答案,这在我的案例中不起作用.


小智 5

ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'
Run Code Online (Sandbox Code Playgroud)


小智 5

在Linux系统上获取本地ipv4-地址的最短方法:

hostname -I | awk '{print $1}'
Run Code Online (Sandbox Code Playgroud)

  • 坏。手册页特别告诉您不要对输出顺序进行任何假设。 (5认同)

小智 5

主网络接口IP

ifconfig `ip route | grep default | head -1 | sed 's/\(.*dev \)\([a-z0-9]*\)\(.*\)/\2/g'` | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1
Run Code Online (Sandbox Code Playgroud)


小智 5

在默认网关的网络中查找该计算机的IP地址(例如,排除所有虚拟网络,泊坞桥)。互联网网关,WiFi网关,以太网

ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
Run Code Online (Sandbox Code Playgroud)

在Linux上工作。

测试:

?  ~ ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
192.168.0.114

?  reverse-networking git:(feature/type-local) ? ifconfig wlp2s0
wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.114  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::d3b9:8e6e:caee:444  prefixlen 64  scopeid 0x20<link>
        ether ac:x:y:z  txqueuelen 1000  (Ethernet)
        RX packets 25883684  bytes 27620415278 (25.7 GiB)
        RX errors 0  dropped 27  overruns 0  frame 0
        TX packets 7511319  bytes 1077539831 (1.0 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

488427 次

最近记录:

5 年,11 月 前