Ввод IP-адреса в переменную bash. Есть ли способ лучше

Я пытаюсь найти короткий и надежный способ поместить свой IP-адрес в переменную bash, и мне было любопытно, есть ли более простой способ сделать это. Вот как я это делаю сейчас:

ip=`ifconfig|xargs|awk '{print $7}'|sed -e 's/[a-z]*:/''/'`

Ответ 1

Вы можете посмотреть этот сайт для альтернатив.

Один из способов:

ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'

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

$ /sbin/ifconfig | sed -n '2 p' | awk '{print $3}'

(из http://www.htmlstaff.org/ver.php?id=22346)

Ответ 2

Я тоже борется с этим, пока не нашел там простую команду

hostname -i

Это просто!

Ответ 3

man hostname рекомендует использовать флаг --all-ip-addresses (стенограмма -I) вместо -I, потому что -I работает только если имя хоста может быть разрешено. Итак, вот оно:

hostname  -I

И если вас интересует только первичный, cut it:

hostname  -I | cut -f1 -d' '

Ответ 4

ip - правильный инструмент для использования, так как ifconfig уже давно устарел. Вот команда awk/sed/grep-free, которая значительно быстрее, чем любая другая, размещенная здесь !:

ip=$(ip -f inet -o addr show eth0|cut -d\  -f 7 | cut -d/ -f 1)

(да, это пробел после первого -d)

Ответ 5

Вот лучший способ получить IP-адрес устройства в переменную:

ip=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')

NB Обновление для поддержки новой версии Linux. (работает также со старшими)

ip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

Почему это лучшее?

  1. Hostname -I иногда получает только IP-адрес или, как на моем VPS, он получает 127.0.0.2 143.127.52.130 2a00:dee0:ed3:83:245:70:fc12:d196
  2. Hostnmae -I работает не на всех системах.
  3. Использование ifconfig не всегда дает IP-адрес, который вам нравится.
    а. Это не удастся, у вас есть несколько интерфейсов (Wi-Fi/Etcernet) и т.д.
    б. Основной IP не может быть на первом найденном интерфейсе
  4. Поиск eth0 может завершиться неудачно, если интерфейс имеет другое имя, как на VPS сервере или wifi

    ip route get 8.8.8.8

Пытается получить маршрут и интерфейс для DNS-сервера Googles (не открывает ни одного сеанса)
Тогда легко получить ip или имя интерфейса, если хотите.

Это также может быть использовано для получения ip адреса интерфейса к хосту в мультирутированной сети.

Ответ 6

Команда ifdata (найденная в пакете moreutils) предоставляет интерфейс для легкого извлечения данных ifconfig без необходимости синтаксического анализа вывода ifconfig вручную. Это достигается с помощью одной команды:

ifdata -pa eth1

Где eth1 - имя вашего сетевого интерфейса.

Я не знаю, как работает этот пакет, когда ifconfig не установлен. Как сказал Syncrho в своем ответе, ifconfig устарел на некоторое время и больше не встречается во многих современных дистрибутивах.

Ответ 7

моя короткая версия. Полезно, когда у вас есть несколько интерфейсов и просто нужен основной ip.

host `hostname` | awk '{print $4}'

Ответ 8

Не совсем короче или проще, но он работает для меня:

ip=$(ip addr show eth0 | grep -o 'inet [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o [0-9].*)

Ответ 9

Вы можете получить просто awk, чтобы выполнить все разбор ifconfig:

ip=$(ifconfig | gawk '
    /^[a-z]/ {interface = $1}
    interface == "eth0" && match($0, /^.*inet addr:([.0-9]+)/, a) {
        print a[1]
        exit
    }
')

Ответ 10

Следующие действия выполняются в Mac OS (где нет параметров ip commnand или имени хоста):

#!/bin/bash

#get interface used for defalt route (usually en0)
IF=$(route get default |grep 'interface' |awk -F: '{print $2}');

#get the IP address for inteface IF
#does ifconfig, greps for interface plus 5 lines, greps for line with 'inet '
IP=$(ifconfig |grep -A5 $IF | grep 'inet ' | cut -d: -f2 |awk '{print $2}');
#get the gateway for the default route
GW=$(route get default | awk '/gateway:/ {print $2}');

Ответ 11

Я использую

IFACE='eth0'
IP=$(ip -4 address show $IFACE | grep 'inet' | sed 's/.*inet \([0-9\.]\+\).*/\1/')

Преимущество этого способа состоит в том, чтобы указать интерфейс (переменная IFACE в примере), если вы используете несколько интерфейсов на своем хосте.

Кроме того, вы можете изменить ip команду, чтобы адаптировать этот фрагмент к вашему усмотрению (адрес IPv6 и т.д.).

Ответ 12

Я думаю, самый надежный ответ:

ifconfig  | grep 'inet addr:' | grep -v '127.0.0.1' | awk -F: '{print $2}' | awk '{print $1}' | head -1

и

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

потому что, когда вы не используете head -1, он показывает все ips....

Ответ 13

В моем script мне понадобилась только сетевая часть IP, поэтому я сделал это как

local=$(hostname -I | awk '{print $2}' | cut -f1,2,3 -d".")

Где разрез -f1,2,3 -d "." можно прочитать как "получить первые 3 части, разделенные запятыми" Чтобы изменить интерфейсы, просто измените $2 на свой номер интерфейса, чтобы удалить весь IP-адрес.

Ответ 14

ifconfig | grep -oP "(?<=inet addr:).*?(?=  Bcast)"

При использовании grep для извлечения части строки (как это делают некоторые другие ответы), perl look-ahead и look-behind утверждают ваши друзья.

Быстрое объяснение состоит в том, что в первой скобке (?<=inet addr:) и в последней (?= Bcast) содержатся шаблоны, которые должны быть сопоставлены, но символы, соответствующие этим паттерам, не будут возвращаться grep, только символы, которые находятся между двумя шаблонами и соответствуют шаблону .*?, который найден между наборами скобок, возвращаются.

Пример вывода ifconfig:

eth0      Link encap:Ethernet  HWaddr d0:67:e5:3f:b7:d3  
          inet addr:10.0.0.114  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1392392 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1197193 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1294730881 (1.2 GB)  TX bytes:167208753 (167.2 MB)
          Interrupt:18

Это извлечет ваш IP-адрес из вывода ifconfig:

ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)"

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

ip=$(ifconfig | grep -oP "(?<=inet addr:).*?(?=Bcast)")

Немного более подробное объяснение:

От человека grep:

-o Распечатайте только согласованные (непустые) части совпадающих строк, причем каждая такая часть находится на отдельной выходной строке.

-P Интерпретировать шаблон как регулярное выражение Perl. Это очень экспериментально, и grep -P может предупреждать о нереализованных функциях.

Из permonks.org:

(?<=pattern) является положительным утверждением внешнего вида

(?=pattern) - это положительное утверждение вперед

-o Сообщает grep возвращать только часть строки, которая соответствует шаблону. Функция look-behinds/forwards не рассматривается grep как часть возвращаемого шаблона. ? после .* важен, так как мы хотим, чтобы он искал следующий взгляд вперед после того, как шаблон. * Был сопоставлен, а не искать последнее совпадение вперед. (Это не требуется, если мы добавили регулярное выражение для IP-адреса вместо. *, Но, читаемость).

Ответ 15

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

 ip addr show | awk '
     BEGIN {FS="/"}
     /^[0-9]+: eth[0-9]+.*UP*/ {ss=1}
     ss==1 && /^ +inet / {print substr($1,10); exit 0}
     END {exit 1}'

и обратите внимание, что конкретный интерфейс можно указать после "ip addr show", если вам не нужен только первый eth-интерфейс. И адаптация к ipv6 - это вопрос поиска "inet6" вместо "inet"...

Ответ 16

В моем случае у меня было еще несколько интерфейсов в списке до eth0. По этой команде вы можете получить ip4-адрес для любого интерфейса. Для этого вам нужно изменить eth0 на необходимый интерфейс.

/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'

Ответ 17

"eth3" является необязательным (полезно для нескольких сетевых адаптеров)

ipaddress=`ip addr show eth3 | grep 'inet ' | awk '{ print $2}' | cut -d'/' -f1`