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

165

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

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

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

  • 1
    Вы просто хотите, чтобы ваш компьютер IP локальной сети? т.е. 192.168.0.12
  • 0
    Да, локальный IP, во-первых, их может быть больше одного, но я мог бы жить даже со списком. На данный момент я рад поддерживать только адреса IPv4 и игнорировать IPv6, так как хочу, чтобы он генерировал только хэш.
Показать ещё 1 комментарий
Теги:
ip
ifconfig

25 ответов

293
Лучший ответ

Используйте 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. Однако это только на Linux.

  • 5
    Также обратите внимание, что в OSX sed использует опцию -E для Extended RE, а не опцию -r GNU-style.
  • 0
    @ghoti Linux поддерживает оба, но только документы -r верно ли обратное для OSX?
Показать ещё 14 комментариев
128

Для Linux-машин (не OS X):

hostname --ip-address
  • 9
    Это работает только если имя в DNS. Если нет, вы получите сообщение «имя хоста: имя или служба неизвестна».
  • 31
    hostname -i - эквивалентная краткая форма
Показать ещё 7 комментариев
100

Это вообще не зависит от 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
  • 6
    Метод, который получает первый адрес, полученный hostname -I , ненадежен, потому что (согласно документации) нельзя делать какие-либо предположения о порядке адресов. Поэтому вполне может быть какая-то внутренняя сеть (например, сеть, в которой живут виртуальные машины). Другой метод кажется хорошим.
  • 0
    Спасибо! Я обновил ответ.
Показать ещё 15 комментариев
23

Отредактировано (2014-06-01)

Поскольку оба Os имеют По умолчанию для 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

Nota: Без аргумента эта функция выводится на STDOUT, IP и новой строке с аргументом, ничего не печатается, но создается переменная с именем как аргумент и содержит IP без новой строки.

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

Старая версия этого ответа

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

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

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

Вдохновленный (работа тоже;)

myIP=$(
    ip a s |
    sed -ne '
        /127.0.0.1/!{
            s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/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; }')

расщепляется:

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;
        }')
  • 1
    @sorin: да, теперь это работает с ifconfig. (поскольку sbin не указан в моем пути $PATH указать полный путь, но такой же путь существует и в MacOS. :-)
  • 1
    @Sorin попробуйте это со time чтобы выбрать, который вы будете использовать так долго ...
Показать ещё 1 комментарий
19

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

hostname  -i

или

hostname -I
  • 0
    это работает в каждом случае?
  • 5
    нет. - это может просто сказать вам 127.0.0.1.
Показать ещё 4 комментария
14

Вы также можете получить адрес IP версии 4 eth0, используя эту команду в linux

/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
  • 0
    Лучший ответ для меня! Спасибо @Sathish! ;-)
  • 1
    Я согласен, это самый чистый способ получить IPv4 от eth0.
7

Это работает в 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

Darwin laptop 14.4.0 Ядро Дарвина Версия 14.4.0: Чт май 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

  • 0
    Несмотря на все ответы на этот вопрос, этот, кажется, единственный, который почти соответствует действительности. Просто нужен | head -1 в конце первой строки, чтобы получить интерфейс по умолчанию, а остальное хорошо.
3

в linux

hostname -I

на macOS

ipconfig getifaddr en0

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

  • 1
    для меня это было hostname -i с более низким I.
3

Предполагая, что вам нужен ваш основной общедоступный IP-адрес, который он видит из остального мира, попробуйте любой из них:

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

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

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

  • 0
    Это не удастся, если нет маршрута по умолчанию (но хорошая идея)
  • 0
    Хорошо ... Предположим, что вы работаете, даже если у вас нет интернета?
3

Первичный сетевой интерфейс 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
2

Я просто использую Имена сетевого интерфейса, моя пользовательская команда

[[ $(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 ~]$

но если сетевому интерфейсу принадлежит хотя бы один 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}', предоставленная ссылкой, более точна, что еще более короткое.

2

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

ifconfig | grep "inet " | cut -f2 -d' '
  • 1
    один маленький вариант: ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
2

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

hostname -I | awk '{print $1}'
  • 5
    Плохой. Страница man говорит вам конкретно не делать никаких предположений о порядке вывода.
2
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'
2

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

ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'
  • 0
    Не работает на CentOS 7.0
  • 0
    @BenoitBlanchon Тогда используйте этот ip route get 1 | awk '{print $NF;exit}' . Должно работать на большинстве систем.
Показать ещё 1 комментарий
1

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

По-моему, эти два QAs лучше всего видны:

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

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

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

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

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

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

myip -i

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

myip -e

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

#!/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 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
0

Если у вас установлены npm и node: npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"

0

Это проще читать: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr:

  • 0
    не работает на macOS 10.12.6
0

Для linux вам нужна эта команда:

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

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

  • 0
    Нет, это не работает.
0

Работает на Mac, Linux и внутри Docker Containers:

$ 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; Выход} ')

Также работает на 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}')}

  • 0
    Mac не работает: hostname --ip-address => hostname: illegal option -- - на macOS Sierra
0
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]*' 
0

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

ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2
0
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
  • 0
    не работает на macOS 10.12.6
-1

На Mac рассмотрите следующее:

scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
  • 1
    Вывод команды scutil --nwi не включает IP-адрес моего Macbook, работающего под управлением Sierra.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню