IP локального хоста

IP локального хоста

Как экземпляр Linux определяет свой IP-адрес?

То есть не 127.0.0.1.

Сохраняется ли это в файле или ifconfig каким-то образом вычисляет это при каждом вызове?

Мне удалось решить эту задачу, просто чтобы показать, что я приложил усилия, но это не то, что я бы включил в серьезное приложение:

sudo ifconfig | head -n 2 | tail -n 1 | tr -s " " | tr " " ":" | cut -d":" -f 4

решение1

В вашем вопросе есть фундаментальные недостатки. Во-первых, хосты могут (и, скорее всего, будут) иметь более одного адреса (например, несколько интерфейсов) и даже более одного адреса на интерфейс. Это еще большая проблема с IPv6, где каждый глобально подключенный хост как минимумдваадреса.

Во-вторых, «лучший» способ сделать это из оболочки будет отличаться от системы к системе.

Линукс:

/sbin/ip addr show eth0 | awk -F"[ /]+" '/inet / {print $3}'

>= Солярис 11:

ipadm show-addr net0/v4 | awk -F"[ /]+" '/ok/ {print $5}'

Mac OS X/Darwin:

ipconfig getifaddr en0

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

ifconfig eth0 | awk -F"[ :]+" '/inet / {print $4}'

Если вы используете более сложный язык, например perl, ruby, java и т. д., вместо оболочки, каждый язык будет иметь свой собственный способ получения этих данных из ядра. Я оставлю поиск этого на ваше усмотрение.

решение2

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

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

Часто IP-адрес, который вас интересует, связан с маршрутом по умолчанию. В большинстве конфигураций вы можете получить нужный интерфейс с помощью команды route, а затем извлечь IP-адрес этого интерфейса с помощью ifconfig.

/sbin/ifconfig $(/sbin/route -n |
                 awk '$1 == "0.0.0.0" {print $8}') |
awk 'match($0, /inet addr:[.0-9]+/) {print substr($0, RSTART+10, RLENGTH-10)}'

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

На вариантах unix, отличных от Linux, вам, возможно, придется подправить команды выше. Большинство из них имеют команды с именами ifconfigи route, но формат вывода может отличаться.

В Linux вместо ifconfigи routeможно использовать ipкоманду изiproute2набор инструментов. Хотя авторы iproute2 считают ifconfigи routeустаревшими, на самом деле использование дает мало преимуществ ip, поскольку вывод ipне намного проще для анализа, а ifconfigи routeвсегда доступны, тогда как некоторые урезанные установки Linux не содержат ip.

решение3

Все ответы здесь технически верны, но они не являются тем, что я бы считал "правильным" ответом. К сожалению, ваш вопрос крайне расплывчат (что я могу понять, если вы не очень хорошо разбираетесь в работе сетей в Linux), поэтому я дам несколько ответов на возможные интерпретации вопроса.


Основной IP-адрес машины

Машина имеет один IP выше всех остальных, который считается основным IP машины. Обратите внимание, что это довольно бессмысленно, так как у коробки может быть несколько IP, и какой из них будет использоваться, зависит от того (я расскажу об этом немного позже).

Основной IP — это просто IP, связанный с именем хоста машины. Вы можете узнать этот IP, выполнив следующее

getent hosts "$(hostname)" | awk '{ print $1 }'

Теперь, что делает эта команда, так это ищет IP для имени хоста машины в соответствии с /etc/nsswitch.conf. В большинстве случаев /etc/nsswitch.confфайл содержит hosts: files dns. Это означает, что при попытке выполнить любой поиск имени хоста или адреса, он /etc/hostsсначала будет искать, а затем консультироваться с DNS (как настроено в /etc/resolv.conf).
Таким образом, команда, getent hosts "$(hostname)"скорее всего, извлечет соответствующую запись из /etc/hosts. awkПросто извлекает только IP из этой строки.

( getentэто просто простая утилита для запроса «баз данных», перечисленных в /etc/nsswitch.conf)


IP-адрес, используемый для связи с внешним миром

Как я уже упоминал ранее, основной IP машины не имеет особого значения. Машина может использовать любой из нескольких IP для связи. В вашем случае у вас, скорее всего, есть только один интерфейс и один (нелокальный) IP. Однако сервер может иметь несколько интерфейсов или IP (иногда несколько IP на одном интерфейсе).
Какой IP будет использоваться, определяется таблицей маршрутизации ядра. Я не буду вдаваться в подробности того, как работает таблица маршрутизации, поскольку это непросто (есть несколько таблиц маршрутизации, и какая из них будет использоваться, зависит от правил выбора таблицы). Я просто расскажу вам, как узнать, какой IP будет использоваться.

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

ip route get 1.2.3.4

(при этом 1.2.3.4IP-адрес будет местом назначения)

На моем компьютере, если я сделаю это с одним из IP-адресов google.com ( 74.125.139.102), я получу следующее:

74.125.139.102 via 192.168.0.1 dev wlan0  src 192.168.0.24 
    cache 

Это говорит мне о том, что IP-адрес 192.168.0.24будет использоваться всякий раз, когда мой компьютер будет подключаться к 74.125.139.102.

Если вам нужен только IP, вы можете просто добавить дополнительный адрес grepв конце.

ip route get 1.2.3.4 | grep -oP '(?<=src )\S+'

grepиспользуется вместо , awkпотому что он менее подвержен ошибкам. Возможно, строка может измениться, и IP не будет в том же месте, но он всегда будет следовать за "src", поэтому мы просто берем значение сразу после "src"


IP-адрес шлюза по умолчанию

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

ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')"

Это даст вам строку, похожую на ту, что в разделе выше. Значение src— это IP, который будет использоваться для трафика, проходящего через шлюз по умолчанию.

Как и в предыдущем разделе, чтобы получить только IP, добавьте grep.

ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')" | grep -oP '(?<=src )\S+'

решение4

Ваш запрос неоднозначен, обычно под словом «localhost» подразумевают интерфейс loopback, а 127.0.0.1 — наиболее распространенный и правильный ответ.

Чего вам не хватает, так это:

  • тот факт, что каждый интерфейс может иметь свой IP-адрес, интерфейс обратной связи является сетевым интерфейсом, таким же, как ваша сетевая карта Ethernet или беспроводной USB-приемник.
  • как следствие, у одного ПК нет единого IP-адреса, все зависит от того, какой интерфейс вы рассматриваете и сколько интерфейсов вы используете в своей ОС.

Вас, вероятно, заинтересует тема «Таблицы маршрутизации ядра», которая является хорошим способом начать понимать, как ядро ​​обрабатывает вашу сетевую активность.

Связанный контент