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


339

Я шукаю рішення командного рядка, яке поверне мені основну (першу) IP-адресу localhost, крім 127.0.0.1

Рішення повинно працювати як мінімум для Linux (Debian і RedHat) та OS X 10.7+

Я знаю, що ifconfigце доступно для обох, але його вихід не є таким послідовним між цими платформами.


2
Ви просто хочете IP локальної мережі вашого пристрою? тобто 192.168.0.12
Кріс Сеймур

Так, локальний IP, по-перше, так як він може мати більше одного, але я міг би жити навіть зі списком. На даний момент я радий підтримувати лише IPv4 адреси та ігнорувати IPv6, оскільки хочу, щоб він генерував хеш.
sorin

2
Як ви визначаєте "первинний"? Якщо ви думаєте "IP-адреса, яка знаходиться в тій самій підмережі, що і мій маршрут за замовчуванням", вам потрібно буде трохи запрограмувати для цього. Але що робити, якщо машина не має типового маршруту, але все ж має> 1 IP-адресу?
ghoti

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, а не параметр у стилі GNU -r.
ghoti

1
Цікаво; Я не розумів, що GNU sed підтримує -E. Останні версії FreeBSD додали цю -rопцію як псевдонім для -Eполегшення переносимості скриптів, але оновлення ще не було передано до OSX. Останнє, що я перевірив, досі використовує версію sed з випуску FreeBSD кілька років тому. Не точно знаєте, який саме з них, як OSX за кілька років прихиляв вихідний код FreeBSD. Я вважаю, що використання -Eбуло призначене порівняти grepз -Eваріантом. Не маю ідеї, чому -rзамість цього обрали людей з GNU .
ghoti

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

1
Я знайшов проблему, хоча ця робота працює на OS X, вона повертає більше ніж один IP, список IP-адрес. Здається, що перший є правильним, але все-таки це порушило б мою логіку. Див. Gist.github.com/ssbarnea/31b9dcb0f8fd528b958c - він також повертає vnic, які є активними, але використовуються паралелями.
sorin

13
OSX: ipconfig getifaddr en0
parleer

232

Наступне буде працювати на 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}'працює, коли я отримую уїд доданий до виходу
Хрітік,

13
ЦЕ (перше) - ЄДИН ПРАВИЛЬНЕ РІШЕННЯ . Це важливо , щоб прочитати IP конкретно з інтерфейсу , пов'язаний з маршрутом за замовчуванням. Інакше ви, ймовірно, отримаєте якусь непотрібну внутрішню адресу.
Ян Худек

12
він не працював для мене, але він був досить закритий:ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
estani

230

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

hostname --ip-address

10
Це працює лише в тому випадку, якщо ім'я вказано в DNS. Якщо ні, ви отримуєте повідомлення "ім'я хоста: ім'я або послуга невідомі".
Вебйорн Льоса

39
hostname -i- еквівалентна коротка форма
Пол Еванс

75
Іноді це просто поверне 127.0.0.1. Якщо це можливо, краще використовуйте ім'я хоста -I, як рекомендовано в посібнику (Ubuntu): "--ip-адреса Відображає мережеві адреси імен хоста. Зверніть увагу, що це працює лише в тому випадку, якщо ім'я хоста можна вирішити. Уникайте використання цей параметр; замість цього використовуйте ім'я хоста --all-ip-адреси. "
jrierab

1
Він також не працює в Linux, принаймні, не hostnameв GNU Coreutils версії 8.26.
ack

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

62

на Linux

hostname -I

на macOS

ipconfig getifaddr en0

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


1
для мене це було hostname -iз нижчим я.
Павло Войташек

2
@PaulWoitaschek сторінка керівництва для малої -iпрапора каже , що це: Avoid using this option; use hostname -I instead.
Борис

@Boris, якщо ви працюєте в чомусь подібному докерному контейнері під керуванням Alpine (і, таким чином, BusyBox), він прийме лише малі літери -i прапор
bayetovsky

40

Рішення

$ 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 без нового рядка .

Nota2: Це було перевірено на Debian, LaCie зламав нас та MaxOs. Якщо це не спрацює у вашому середовищі, мене дуже зацікавлять відгуки!

Старіший варіант цієї відповіді

(Не видаляється, оскільки базується на 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. :-)
F. Hauri

1
@sorin спробуйте це, timeщоб вибрати, який би ви використовували так довго ...
F. Hauri

швидке і мале рішення було найкращим підходом. Новіші рішення дають мені синтаксичні помилки. Сумісність - це завжди плюс. Дякую.
м3нда

29

Характерно лише для певних збірок Ubuntu. Хоча це може просто сказати вам 127.0.0.1:

hostname  -i

або

hostname -I

чи працює це у кожному випадку?
AloneInTheDark

6
ні. - це може просто сказати вам 127.0.0.1.
SvenDowideit

hostname -Я працює на ubuntu.
Борж

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

1
використовувати ім'я хоста -I або ім'я хоста --all-ip-адреси
Айдін К.

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

Це найелегантніший метод, якщо ви знаєте інтерфейс. Ідеально, якщо у вашій системі є кілька інтерфейсів, але ви просто зацікавлені в конкретному.
lepe

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

Ноутбук Darwin 14.4.0 Darwin Kernel Версія 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.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в кінці першого рядка, щоб отримати інтерфейс за замовчуванням, а решта добре.
Ендарет

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}'"
Сем Х'юстон

Правильно. Але питання спочатку було про команду. Тож я щойно доречно розмістив. Ура!
Faizan Noor

6

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

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

5
Поганий. Сторінка "man" дозволяє вам конкретно не робити припущень щодо порядку виводу.
Метт

Чудово підходить для моїх дрібницьких випадків використання - мені байдуже, чи швидко і брудно! Чудово!
Nicolai Weitkemper

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

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 тощо) і прийшов до рішення об’єднати всі найкращі рішення в один сценарій оболонки.

На мою думку, ці два КА найкращі:

Як я можу отримати свою зовнішню 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:~#

Дебіан Джессі

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}'. Має працювати над більшою частиною системи.
Jotne

Справді 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:

$ 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 Сьєрра
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.