Как получить основной IP-адрес локальной машины на Linux и OS X?



Я ищу решение командной строки, которое вернуло бы мне основной (первый) IP-адрес localhost, кроме 127.0.0.1



решение должно работать по крайней мере для Linux (Debian и RedHat) и OS X 10.7+



Я знаю, что ifconfig доступно на обоих, но его выход не очень согласуются между этими платформами.

741   30  

30 ответов:

использовать 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]*).*//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]*).*//p'"

гораздо более простой способ-это hostname -I (hostname -i для более старых версий hostname но см. комментарий). Однако, это только на Linux.

для linux машин (не OS X):

hostname --ip-address

следующее будет работать на Linux, но не OSX.

это не зависит от DNS вообще, и это работает, даже если /etc/hosts не установлен правильно (1 является сокращением для 1.0.0.0):

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

или избежать awk и используя публичный DNS Google в 8.8.8.8 для очевидности:

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

менее надежный способ: (см. комментарий ниже)

hostname -I | cut -d' ' -f1

редактировать ( 2014-06-01 2018-01-09)

для более сильной конфигурации, со многими интерфейсами и многими IP, настроенными на каждом интерфейсе, я написал чисто Баш скрипт (не на основе 127.0.0.1) для поиска правильного интерфейса и ip, основанный на default route. Я размещаю этот скрипт в самом низу этого ответа.

интро

как ОС Баш установленные по умолчанию, есть совет bash для Mac и Linux:

проблема локали предотвращается с помощью 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

Fancy tidy:

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}  "%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 и A новая строка, С аргументом ничего не печатается, но переменная с именем в качестве аргумента создается и содержит IP без новая строка.

Nota2: это было проверено на Debian, LaCie взломал nas и MaxOs. Если это не будет работать под вашим окружением, я буду очень заинтересован обратными связями!

более старая версия этого ответа

( не удаляется, потому что на основе sed, а не bash. )

предупреждаю: есть проблема с локалями!

быстрый и маленький:

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

взорвался (тоже работа;)

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

Edit:

как! Это, кажется, не работает на 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; }')

splitted:

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

мой сценарий (Ян 2018):

этот скрипт сначала найдет ваш маршрут по умолчанию и интерфейс используется для, а затем поиск локальной сети IP соответствия шлюз и заполнить переменные. Последние две строки просто напечатать, что-то вроде:

Interface   : en0
Local Ip    : 10.2.5.3
Gateway     : 10.2.4.204
Net mask    : 255.255.252.0
Run on mac  : true

или

Interface   : eth2
Local Ip    : 192.168.1.31
Gateway     : 192.168.1.1
Net mask    : 255.255.255.0
Run on mac  : false

вот он:

#!/bin/bash
runOnMac=false
int2ip() { printf ${2+-v}  "%d.%d.%d.%d" \
        $((>>24)) $((>>16&255)) $((>>8&255)) $((&255)) ;}
ip2int() { local _a=(${1//./ }) ; printf ${2+-v}  "%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

вы также можете попробовать это, хотя он может просто сказать вам 127.0.0.1:

hostname  -i

или

hostname -I

вы также можете получить IP-адрес версии 4 eth0 с помощью этой команды в linux

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

вывод будет таким

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

на linux

hostname -I

на macOS

ipconfig getifaddr en0

отметим, что hostname -I может возвращать несколько адресов в ненадежном порядке (см. man hostname). Но для меня это просто возвращает 192.168.1.X чего вы хотели.

решение

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

объяснение

The правильно способ запроса сетевой информации использует 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

чтобы извлечь the src ip,sed - это ligthest и наиболее совместим с поддержкой регулярных выражений:

  • -n нет вывода по умолчанию
  • 's/pattern/replacement/p' матч шаблон и замена печати только
  • .*src \([0-9.]\+\).* сопоставьте src IP, используемый ядром, чтобы достичь 8.8.8.8

например, окончательный вывод:

192.168.8.16

другие ответы

я думаю, что ни один из предыдущих ответов не достаточно хорошо для меня, так как они не работают в машине (в Gentoo 2018).

вопросы, которые я нашел с предыдущими ответами:

  • использование позиционного столбца в выводе команды;
  • использование ifconfig который является устаревшим и-например - не перечислять несколько IP-адресов;
  • использование awk для простой задачи, с которой sed может справиться лучше;
  • ip route get 1 неясно, и на самом деле псевдоним для ip route get to 1.0.0.0
  • использование hostname команда, которой нет -I опция во всех устройствах и какой возврат 127.0.0.1 в моем случае.

это работает на Linux и OSX

это позволит получить интерфейс, связанный с маршрутом по умолчанию

NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr(,74,10); print thif;} /^default.*UG/ {thif=substr(,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

Darwin laptop 14.4.0 Darwin Kernel Version 14.4.0: чт 28 мая 11: 35:04 PDT 2015; корень: 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.местные 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

используя некоторые другие методы, вы можете ввести конфликт, в котором в системе определено несколько IP-адресов. Эта строка всегда получает IP-адрес по умолчанию используется.

ip route get 8.8.8.8 | head -1 | awk '{print }'

первичный сетевой интерфейс IP

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

самый короткий способ получить локальный ipv4-адрес в вашей системе linux:

hostname -I | awk '{print }'

Я должен добавить к ответу Коллина Андерсона, что этот метод также учитывает, если у вас есть два интерфейса, и они оба отображаются как вверх.

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

Я работал над приложением с Raspberry Pi и нуждался в IP-адресе, который фактически использовался не только независимо от того, был ли он включен или нет. Большинство других ответов вернут оба IP-адреса, что не обязательно полезно - для моего сценария в любом случае.

Не уверен, что это работает во всех ОС, попробуйте.

ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print }'
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print  }' | sed 's|/.*||'

другое ifconfig вариант, который работает как на Linux, так и на OSX:

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

Я прошел через множество ссылок (StackExchange, AskUbuntu, StackOverflow и т. д.) и пришел к решению объединить все лучшие решения в один сценарий оболочки.

на мой взгляд, эти два QAs являются лучшими из увиденных:

как я могу получить свой внешний IP-адрес в сценарии оболочки? https://unix.stackexchange.com/q/22615

как найти мой внутренний ip-адрес? https://askubuntu.com/a/604691

вот мой решение, основанное на некоторых идеях rsp, разделенных в его репозитории (https://github.com/rsp/scripts/).

некоторые из вас могут сказать, что этот сценарий очень огромный для такой простой задачи, но я хотел бы сделать его легким и гибким в использовании насколько это возможно. Он поддерживает простой файл конфигурации, позволяющий переопределить значения по умолчанию.

он был успешно протестирован под Cygwin, MINGW и Linux (Red Hat).

показать внутренний IP адрес

myip -i

показать внешний IP-адрес

myip -e

исходный код, также доступный по ссылке:https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip. пример конфигурационного файла находится рядом с основным скриптом.

#!/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 "" )/myip.conf" \
    ~/.myip.conf \
    /etc/myip.conf
do
    [ -f "$f" ] && {
        . "$f"
        break
    }
done

# =========================================================================

show_usage() {
    cat - <<HELP
USAGE
  $( basename "" ) [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 "" ): $@" >&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 "" && return
        getent ahostsv4 "" \
        | grep RAW \
        | awk '{ print ; 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  }'
        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

Я просто использовать Имена Сетевых Интерфейсов мои пользовательские команды

[[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@p'
192.168.2.221
[flying@lempstacker ~]$

но если сетевой интерфейс владеет хотя бы одним ip, то он покажет, что все ip принадлежат ему

Ubuntu 16.10

root@yakkety:~# sed -r -n 's@"@@g;s@^VERSION=(.*)@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@p'
178.62.236.250
root@yakkety:~#

Debian Jessie

root@jessie:~# sed -r -n 's@"@@g;s@^PRETTY_NAME=(.*)@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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 как видно из остального мира, попробуйте любой из них:

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

есть пакет узлов для всего. Перебор? Возможно. Простой в использовании и запомнить? Ясное дело!.

$ npm install --global internal-ip-cli

$ internal-ip
fe80::1

$ internal-ip --ipv4
192.168.0.3

я извлекаю свой комментарий к этому ответу:

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

Он основан на ответе @CollinAnderson, который не работал в моем случае.

ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print }'

Если вы знаете сетевой интерфейс (eth0, wlan, tun0 и т. д.):

ifconfig eth0 | grep addr: | awk '{ print  }' | 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 }' | 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]*).*//p' | awk '{print1$; выход}')

работает на 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]*).*//p' | awk '{print ; exit}')}

для linux вам нужна следующая команда:

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

введите это в своей оболочке, и вы просто узнаете свой ip.

это легче читать: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print }' | tr -d addr:

Если у вас npm и node установлено : npm 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}'

Comments

    Ничего не найдено.