Как получить основной 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.