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

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

该解决scheme至less适用于Linux(Debian和RedHat)和OS X 10.7+

我知道ifconfig是可用的,但它的输出在这些平台之间并不那么一致。

使用grepifconfig过滤IP地址:

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将该命令别名以创build自己的命令,称为myip

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

一个更简单的方法是hostname -I 。 但是,这仅限于Linux。

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

 hostname --ip-address 

这完全不依赖于DNS,即使/etc/hosts设置不正确( 11.0.0.0简写):

 ip route get 1 | awk '{print $NF;exit}' 

或者避免使用awk并在8.8.8.8使用Google的公有DNS:

 ip route get 8.8.8.8 | head -1 | cut -d' ' -f8 

一个不太可靠的方法:(见下面的评论)

 hostname -I | cut -d' ' -f1 

编辑(2014-06-01)

由于两个OS都默认安装了bash,所以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 

把它放到一个函数中:

最小:

 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) } 

简单使用:

 getMyIP 192.168.1.37 

花式整齐:

 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 } 

用法:

 getMyIP 192.168.1.37 

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

 getMyIP varHostIP echo $varHostIP 192.168.1.37 set | grep ^varHostIP varHostIP=192.168.1.37 

注意:没有参数,这个函数输出在STDOUT上,IP和一个换行符 ,带有参数,什么都不打印,但是一个名为参数的variables被创build并且包含没有换行符的 IP。

Nota2:这是在Debian上testing的,LaCie攻击了nas和MaxOs。 如果这不能在你的环境下工作,我会非常感兴趣的反馈!

此答案的较早版本

警告:有一个地区的问题!

快和小:

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

爆炸(工作也;)

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

编辑:

怎么样! 这似乎不适用于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; }') 

分裂:

 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; }') 

你也可以试试这个,虽然它可能只是告诉你127.0.0.1

 hostname -i 

要么

 hostname -I 

你也可以在linux下使用这个命令获得eth0的IP版本4地址

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

输出将是这样的

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

这适用于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;}'` 

使用上面发现的接口,获取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'` 

OSX

 uname -a 

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

 echo $NET_IF 

EN5

 echo $NET_IP 

192.168.0.130

CentOS Linux

 uname -a 

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 

为eth0

 echo $NET_IP 

192.168.46.10

主要networking接口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 

不知道这是否适用于所有操作系统,试试看。

 ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}' 

在您的linux系统上获取本地ipv4地址的最简单方法是:

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

另一个可以在Linux和OSX上运行的ifconfig variantion:

 ifconfig | grep "inet " | cut -f2 -d' ' 

使用其他一些方法您可能会在系统上定义多个IP地址的情况下input冲突。 这条线总是获取默认使用的IP地址。

ip route获得8.8.8.8 | 头-1 | awk'{print $ 7}'

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

 wget http://ipecho.net/plain -O - -q curl http://icanhazip.com curl http://ifconfig.me/ip 

在Linux上

 hostname -I 

在macOS上

 ipconfig getifaddr en0 

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

 ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||' 

我经历了很多链接(StackExchange,AskUbuntu,StackOverflow等),并决定将所有最好的解决scheme合并到一个shell脚本中。

在我看来,这两个QA是最好的:

我怎样才能得到我的外部IP地址在一个shell脚本? https://unix.stackexchange.com/q/22615

我如何find我的内部IP地址? https://askubuntu.com/a/604691

这里是我的解决scheme,基于rsp共享的一些想法( https://github.com/rsp/scripts/ )。

你们中的一些人可以说这个脚本对于这么简单的任务来说是非常大的,但是我希望尽可能地使用起来简单灵活。 它支持简单的configuration文件,允许重新定义默认值。

它在Cygwin,MINGW和Linux(Red Hat)下成功testing。

显示内部IP地址

 myip -i 

显示外部IP地址

 myip -e 

源代码,也可通过链接获得: https : //github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip 。 configuration文件的例子在主脚本旁边。

 #!/bin/bash # ========================================================================= # # Getting both internal and external IP addresses used for outgoing # Internet connections. # # Internal IP address is the IP address of your computer network interface # that would be used to connect to Internet. # # External IP address is the IP address that is visible by external # servers that you connect to over Internet. # # Copyright (C) 2016 Ildar Shaimordanov # # ========================================================================= # Details of the actual implementation are based on the following QA: # # How can I get my external IP address in a shell script? # https://unix.stackexchange.com/q/22615 # # How do I find my internal ip address? # https://askubuntu.com/a/604691 # ========================================================================= for f in \ "$( dirname "$0" )/myip.conf" \ ~/.myip.conf \ /etc/myip.conf do [ -f "$f" ] && { . "$f" break } done # ========================================================================= show_usage() { cat - <<HELP USAGE $( basename "$0" ) [OPTIONS] DESCRIPTION Display the internal and external IP addresses OPTIONS -i Display the internal IP address -e Display the external IP address -v Turn on verbosity -h Print this help and exit HELP exit } die() { echo "$( basename "$0" ): $@" >&2 exit 2 } # ========================================================================= show_internal="" show_external="" show_verbose="" while getopts ":ievh" opt do case "$opt" in i ) show_internal=1 ;; e ) show_external=1 ;; v ) show_verbose=1 ;; h ) show_usage ;; \? ) die "Illegal option: $OPTARG" ;; esac done if [ -z "$show_internal" -a -z "$show_external" ] then show_internal=1 show_external=1 fi # ========================================================================= # Use Google's public DNS to resolve the internal IP address [ -n "$TARGETADDR" ] || TARGETADDR="8.8.8.8" # Query the specific URL to resolve the external IP address [ -n "$IPURL" ] || IPURL="ipecho.net/plain" # Define explicitly $IPCMD to gather $IPURL using another tool [ -n "$IPCMD" ] || { if which curl >/dev/null 2>&1 then IPCMD="curl -s" elif which wget >/dev/null 2>&1 then IPCMD="wget -qO -" else die "Neither curl nor wget installed" fi } # ========================================================================= resolveip() { { gethostip -d "$1" && return getent ahostsv4 "$1" \ | grep RAW \ | awk '{ print $1; exit }' } 2>/dev/null } internalip() { [ -n "$show_verbose" ] && printf "Internal: " case "$( uname | tr '[:upper:]' '[:lower:]' )" in cygwin* | mingw* | msys* ) netstat -rn \ | grep -w '0.0.0.0' \ | awk '{ print $4 }' return ;; esac local t="$( resolveip "$TARGETADDR" )" [ -n "$t" ] || die "Cannot resolve $TARGETADDR" ip route get "$t" \ | awk '{ print $NF; exit }' } externalip() { [ -n "$show_verbose" ] && printf "External: " eval $IPCMD "$IPURL" $IPOPEN } # ========================================================================= [ -n "$show_internal" ] && internalip [ -n "$show_external" ] && externalip # ========================================================================= # EOF 

我只是使用networking接口名称 ,我的自定义命令是

 [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 

在我自己的笔记本上

 [flying@lempstacker ~]$ cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [flying@lempstacker ~]$ [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 192.168.2.221 [flying@lempstacker ~]$ 

但是如果networking接口拥有至less一个IP,那么它将显示所有的IP属于它

例如

Ubuntu 16.10

 root@yakkety:~# sed -r -n 's@"@@g;s@^VERSION=(.*)@\1@p' /etc/os-release 16.04.1 LTS (Xenial Xerus) root@yakkety:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 178.62.236.250 root@yakkety:~# 

Debian Jessie

 root@jessie:~# sed -r -n 's@"@@g;s@^PRETTY_NAME=(.*)@\1@p' /etc/os-release Debian GNU/Linux 8 (jessie) root@jessie:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 192.81.222.54 root@jessie:~# 

CentOS 6.8

 [root@centos68 ~]# cat /etc/redhat-release CentOS release 6.8 (Final) [root@centos68 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 162.243.17.224 10.13.0.5 [root@centos68 ~]# ip route get 1 | awk '{print $NF;exit}' 162.243.17.224 [root@centos68 ~]# 

Fedora 24

 [root@fedora24 ~]# cat /etc/redhat-release Fedora release 24 (Twenty Four) [root@fedora24 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' 104.131.54.185 10.17.0.5 [root@fedora24 ~]# ip route get 1 | awk '{print $NF;exit}' 104.131.54.185 [root@fedora24 ~]# 

看来这个命令ip route get 1 | awk '{print $NF;exit}' 链接提供的ip route get 1 | awk '{print $NF;exit}'更精确,而且更短。

如果你知道networking接口(eth0,wlan,tun0等):

 ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2 
 ifconfig | grep "inet addr:" | grep -v "127.0.0.1" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1 
 ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*' 

适用于Mac,Linux和Docker容器:

$ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $ 1; exit}')

也可以在Makefile上使用:

LOCAL_HOST := ${shell hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $1; exit}')}

对于Linux,你需要的是这个命令:

 ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }' 

在你的shell中键入这个,你会知道你的ip。

如果您安装了npmnodenpm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"

在Mac上,请考虑以下几点:

 scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' 

这更容易阅读: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr: