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


339

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

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

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


2
Вы просто хотите, чтобы ваш компьютер IP локальной сети? т.е. 192.168.0.12
— Крис Сеймур

Да, локальный IP, во-первых, их может быть больше одного, но я мог бы жить даже со списком. На данный момент я рад поддерживать только адреса IPv4 и игнорировать IPv6, так как хочу, чтобы он генерировал только хэш.
— сорин

2
Как вы определяете "основной"? Если вы думаете «IP-адрес, который находится в той же подсети, что и мой маршрут по умолчанию», вам нужно немного запрограммировать для этого. Но что, если у машины нет маршрута по умолчанию, но он все еще имеет> 1 IP-адрес?
— Готи

4
Попробуй curl -4 ifconfig.co. Он ответит вашим внешним IP4-адресом.
— Asmaier

Ответы:


475

Используйте 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.


5
Также обратите внимание, что в OSX sed использует -Eопцию Extended RE, а не -rопцию GNU-style .
— Готи

1
Интересный; Я не осознавал, что GNU sed поддерживается -E. Последние версии FreeBSD добавили -rопцию в качестве псевдонима для -Eоблегчения переносимости скриптов, но обновление еще не было перенесено в OSX, в последней проверенной мной версии все еще используется версия sed из релиза FreeBSD несколько лет назад. Не уверен, какой именно, так как OSX несколько раз принимал исходный код FreeBSD несколько лет. Я считаю, что использование -Eбыло предназначено, чтобы быть сопоставимым с grepрусским -Eвариантом. Понятия не имею, почему люди GNU выбрали -rвместо этого.
— Готи

1
@ghoti Я изменил ответ, чтобы использовать его, -Eчтобы быть уверенным в переносимости, можно подумать, что --helpи man pagesон будет обновлен ... это действительно вызвало у меня небольшую путаницу ранее в другом вопросе с использованием-E
— Крис Сеймур

1
Я обнаружил проблему, хотя это работает на OS X, он возвращает более одного IP, список IP-адресов. Кажется, что первый - правильный, но все же это сломало бы мою логику. См. Gist.github.com/ssbarnea/31b9dcb0f8fd528b958c - он также возвращает активные, но используемые параллами vnic.
— Сорин

13
OSX: ipconfig getifaddr en0
— эксперт

235

Следующее будет работать на 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

8
Метод, который получает первый адрес, созданный hostname -Iобъектом, ненадежен, потому что (согласно документации) нельзя делать какие-либо предположения о порядке адресов. Поэтому вполне может быть какая-то внутренняя сеть (например, сеть, в которой живут виртуальные машины). Другой метод кажется хорошим.
— Адам Рычковски

3
Это должен быть принятый ответ, так как RHEL 7 больше не включает ifconfig.
— Андрей

10
Для меня ip route get 1 | awk '{print $(NF-2);exit}'работает, как UID добавлен к выходу
— Hritik

13
ЭТО (первое) ЕДИНСТВЕННОЕ ПРАВИЛЬНОЕ РЕШЕНИЕ . Это важно , чтобы прочитать IP конкретно из интерфейса , связанный с маршрутом по умолчанию. В противном случае вы, скорее всего, получите какой-то бесполезный внутренний адрес.
— Ян Худек

12
это не сработало для меня, но было закрыто достаточно:ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
— Эстани

229

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

hostname --ip-address

10
Это работает только если имя в DNS. Если нет, вы получите сообщение «имя хоста: имя или служба неизвестна».
— Вебьорн Лёса

39
hostname -iэто эквивалентная короткая форма
— Пол Эванс

75
Иногда это просто возвращает 127.0.0.1. Если доступно, лучше использовать имя хоста -I, как рекомендовано в руководстве (Ubuntu): "--ip-address Показать сетевой адрес (а) имени хоста. Обратите внимание, что это работает, только если имя хоста может быть разрешено. Избегайте использования эта опция; вместо этого используйте hostname --all-ip-address. "
— jrierab

1
Он также не работает в Linux, по крайней мере, hostnameв GNU Coreutils версии 8.26.
— извед

5
На моей машине hostname -iвыдает только локальный IP, в то время как hostname -Iвыдает все остальные IP
— Alexis Paques

61

в Linux

hostname -I

на macOS

ipconfig getifaddr en0

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


1
для меня это было hostname -iс более низким I.
— Павел Войташек

2
@PaulWoitaschek страница руководства для строчной -iфлага говорит , что это: Avoid using this option; use hostname -I instead.
— Борис

@ Борис, если вы работаете в чем-то вроде док-контейнера с запущенным Alpine (и, следовательно, BusyBox), он будет принимать только строчный флаг -i
— bayetovsky

41

Решение

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

объяснение

Правильный путь к сетевой информации запроса с помощью 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

Чтобы извлечь srcip, sedон самый легкий и наиболее совместимый с поддержкой регулярных выражений:

  • -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в моем случае.

34

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

Для более сильной конфигурации, с множеством интерфейсов и множеством IP-адресов, настроенных на каждом интерфейсе, я написал чистый bash- скрипт (не основанный на 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

Причудливая приборка:

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

Примечание 2: Это было протестировано на Debian, LaCie, взломанных NAS и MaxO. Если это не сработает в вашей среде, мне будут очень интересны отзывы!

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

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

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

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

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

Редактировать:

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

Мой сценарий (январь 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} $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

1
@sorin: да, теперь это работает с ifconfig. (поскольку sbinэто не $PATHуказывается в моем полном пути, но в MacOS также должен существовать такой же путь. :-)
— Ф. Хаури

1
@sorin попробуйте это с помощью, timeчтобы выбрать то, что вы будете использовать так долго ...
— Ф. Хаури

быстрое и маленькое решение было лучшим подходом. Новые решения дают мне синтаксические ошибки. Совместимость это всегда плюс. Спасибо.
— m3nda

28

Специфично только для определенных сборок Ubuntu. Хотя это может просто сказать вам 127.0.0.1:

hostname  -i

или

hostname -I

это работает в каждом случае?
— AloneInTheDark

6
нет. - это может просто сказать вам 127.0.0.1.
— SvenDowideit

имя хоста - я работаю на Ubuntu.
— Борж

1
$ hostname --ip-addressпросто дает мне 127.0.0.1на Arch Linux
— kristianlm

1
используйте имя хоста -I или имя хоста --all-ip-address
— Айдын К.

24

Вы также можете получить 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

Лучший ответ для меня! Спасибо @Sathish! ;-)
— Самуэль Фан

1
Я согласен, это самый чистый способ получить IPv4 от eth0.
— Крис Мендес

Предполагается, что eth0 не является текущей стратегией именования и никогда не гарантировалось в качестве основного интерфейса.
— rfay

Это самый элегантный метод, если вы знаете интерфейс. Идеально, если ваша система имеет несколько интерфейсов, но вы просто заинтересованы в конкретном.
— Леп

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

Используя интерфейс, обнаруженный выше, получите 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 Darwin Kernel Версия 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 четверг 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


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

12

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

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

Он потерпит неудачу, если маршрут по умолчанию отсутствует (но хорошая идея)
— FractalSpace

Хорошо ... Предположим, что вы работаете, даже если у вас нет интернета?
— Борис Чурзин

8

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

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

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


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

1
Если вы хотите сделать это bashпсевдонимом:alias myip="ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print \$2}'"
— Сэм Хьюстон,

Правильно. Но вопрос изначально был о команде. Так что я только что опубликовал актуально. Ура!
— Файзан Нур

6

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

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

5
Плохой. Страница man специально говорит вам не делать никаких предположений о порядке вывода.
— Мэтт

Прекрасно работает для моих тривиальных вариантов использования - мне все равно, если это быстро и грязно! Большой!
— Николай Вайткемпер

6

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

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

6

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

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

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


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

5

Находит IP-адрес этого компьютера в сети, которая является шлюзом по умолчанию (например, исключает все виртуальные сети, док-мосты), например. Интернет-шлюз, Wi-Fi-шлюз, Ethernet

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

Работает на 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

Ницца! Программирование Taco Bell в лучшем виде - спасибо за это.
— Стиви Ховард


3

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

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

1
одна маленькая вариация:ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
— jpbochi

Почему половина этих ответов вообще не работает для меня?
— SurpriseDog

3

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

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

Как я могу получить свой внешний 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 "$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

3

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

[[ $(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 Джесси

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 | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'

Не работает на CentOS 7.0
— Бенуа Бланшон

@BenoitBlanchon Тогда используйте это ip route get 1 | awk '{print $NF;exit}'. Должно работать на большинстве систем.
— Йотн

Действительно ip route get 1 | awk '{print $NF;exit}'работает
— Бенуа Бланшон

2

Существует пакет узлов для всего. Это кроссплатформенный и простой в использовании.

$ npm install --global internal-ip-cli

$ internal-ip
fe80::1

$ internal-ip --ipv4
192.168.0.3

Это спорный подход, но использование npm для инструментов становится все более популярным, нравится вам это или нет.


1

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

ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2


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]*' 

1

Работает на 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}')}


Mac не работает: hostname --ip-address=> hostname: illegal option -- -на macOS Sierra
— JL Peyret

1

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

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

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


Нет, это не работает.
— FractalSpace


1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.