Как я могу получить свой собственный IP-адрес и сохранить его в переменной в скрипте оболочки?
networking
shell-script
ip
Том Брито
источник
источник
Ответы:
Это не так просто, если вы хотите принять во внимание WLAN и другие альтернативные интерфейсы. Если вы знаете, для какого интерфейса вам нужен адрес (например, eth0, первая плата Ethernet), вы можете использовать это:
Другими словами, получите мне информацию о конфигурации сети, найдите
eth0
, получите эту строку и следующую (-A 1
), получите только последнюю строку, получите вторую часть этой строки при разделении с:
, затем получите первую часть этого при разделении с пространством.источник
grep
код в ваш код, чтобы игнорировать любой интерфейс с "eth0:" в нем; теперь это работает, как я ожидаю (давая только IP-адрес "eth0", а не какие-либо подчиненные интерфейсы (eth0: 0, eth0: 1 и т. д.):ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
ifconfig eth0
ip address
вместо этогоЯ полагаю, что "современные инструменты" способ получить ваш адрес IPv4 состоит в том, чтобы анализировать "ip", а не "ifconfig", так что это будет что-то вроде:
или что-то типа того.
источник
ip
доступно на всех дистрибутивах Red Hat и Fedora, которые я использовал.ip
является частью пакета iproute2 ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ).ifconfig
иroute
предположительно устарели, хотя они продолжают использоваться многими людьми, особенно в сценариях.ip
по моему мнению, гораздо более приятный.ip
также доступен на всех дистрибутивах Debian и Debian, которые я видел. Это часть пакета iproute, которая помечена как важная.ip
является частью пакета iproute2, который по умолчанию является дистрибутивом. Это в большинстве хороших репозиториев. en.wikipedia.org/wiki/Iproute2/sbin/ip
вместоip
?awk
иcut
немного забавно для меня, вот возможная альтернатива, которая на самом деле не может быть лучше:ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
Почему бы просто не сделать
IP=$(hostname -I)
?источник
hostname -i
дает мне просто127.0.0.1
,hostname -I
дает мне правильный IP-адрес ...-i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses
/etc/hosts
вместе с соответствующим IP-адресом-I
на FreeBSD, но вы можете использоватьdig +short `hostname -f`
Если вам нужен адрес интерфейса, проще всего установить moreutils, тогда:
ifdata
отвечает практически на каждый вопрос, для которого у вас возникнет искушение разобратьifconfig
вывод.Если вы хотите узнать свой IP-адрес так, как его видит внешняя сторона (помимо NAT и т. Д.), Существует множество сервисов, которые это сделают. Один из них довольно прост:
источник
ifdata
добавить вiproute2
. Возможно, новый бинарный файл называетсяipdata
Чтобы получить адреса IPv4 и IPv6 и не предполагать, что основным интерфейсом является
eth0
(в наши дниem1
это более распространено ), попробуйте:-o
использует формат вывода одной строки, который легче обрабатывать сread
,grep
и т.д.up
исключает устройства, которые не активныscope global
исключает частные / локальные адреса, такие как127.0.0.1
иfe80::/64
primary
исключает временные адреса (если вы хотите, чтобы адрес не менялся)источник
-4
/-6
фильтровать типы адресов. Вы также можете легко получить другие параметры интерфейса. Лично мне не нравится цикл while, и я предпочитаюgrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Зависит от того, что вы подразумеваете под собственным IP-адресом. Системы имеют IP-адреса в нескольких подсетях (иногда несколько в каждой подсети), некоторые из которых IPv4, некоторые IPv6 используют такие устройства, как сетевые адаптеры, петлевые интерфейсы, VPN-туннели, мосты, виртуальные интерфейсы ...
Если вы имеете в виду IP-адрес, по которому другое данное устройство может достигать вашего компьютера, вы должны выяснить, какая это подсеть, и о какой версии IP мы говорим. Также имейте в виду, что из-за NAT, выполняемого брандмауэром / маршрутизаторами, IP-адрес интерфейса может не совпадать с тем, что удаленный хост видит входящее соединение с вашего компьютера.
При наличии причудливой маршрутизации от источника или по протоколу / порту может быть сложно определить, какой интерфейс будет использоваться для связи с одним удаленным компьютером по заданному протоколу, и даже в этом случае нет гарантии, что IP-адрес этого интерфейса может быть напрямую адресуется удаленным компьютером, желающим установить новое соединение с вашим компьютером.
Для IPv4 (вероятно, работает и для IPv6), хитрость, которая работает во многих приложениях, включая Linux, для определения IP-адреса интерфейса, используемого для доступа к данному хосту, заключается в использовании connect (2) на сокете UDP и использовании getsockname ():
Например, на моем домашнем компьютере:
Будет использоваться для определения IP-адреса интерфейса, через который я достигну 8.8.8.8 (DNS-сервер Google). Он будет возвращать что-то вроде «192.168.1.123», который является адресом интерфейса для маршрута по умолчанию в Интернет. Тем не менее, Google не будет видеть DNS-запрос от моего компьютера как поступающий с этого IP-адреса, который является частным, поскольку есть NAT, выполняемый моим домашним широкополосным маршрутизатором.
connect () на сокете UDP не отправляет никакого пакета (UDP не использует соединение), но подготавливает сокет путем запроса таблицы маршрутизации.
источник
источник
-I
вместо-i
лучше, так как вы хотите игнорировать петлевые адреса, поэтому последняя команда будетipa=$(hostname -I|cut -f1 -d ' ')
grep
этого недостаточно, не связывайте это с чем-то другим. Просто используйте что - то другое (sed
,awk
и т.д.).Я не хочу быть придурком, но действительно есть верный путь, и это все. Вы обрезаете вывод,
ip route
чтобы получить только исходный IP. В зависимости от того, какой IP вы пытаетесь достичь, «мой собственный IP-адрес» (слова ОП) будет отличаться. Если вы хотите получить доступ к общедоступному Интернету, использование DNS-сервера Google 8.8.8.8 довольно стандартно. Так...Краткий ответ:
Вот подробное объяснение
Если я хочу, чтобы IP-адрес, который я использую для доступа в Интернет , я использую это:
Если я хочу, чтобы ip, который я использую, достигал чего-то в моей VPN , я использую это:
Если бы я хотел, чтобы IP-адрес, который я использую, достигал самого себя , я использовал бы это:
Подробнее об этой
sed
командеПрежде всего позвольте мне сказать, что при выборе инструментов Unix вы пытаетесь выбрать инструменты, которые требуют наименьшего количества каналов. Таким образом, в то время как некоторые ответы будут трубы
ifconfig
доgrep
доsed
доhead
, что редко когда это необходимо. Когда вы видите это, это должно поднять красный флаг, что вы принимаете советы от кого-то с небольшим опытом. Это не делает «решение» неправильным. Но это, вероятно, может использовать некоторую оптимизацию.Я выбрал,
sed
потому что это более кратко, чем тот же рабочий процесс вawk
. (У меня есть пример awk ниже.) Я не думаю, что какой-либо другой инструмент, но эти 2 были бы уместны.Давайте посмотрим, что
Примечание:sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
делает:Раньше я использовал,
sed -n '/src/{s/.*src *//p;q}'
но комментатор указал, что у некоторых систем есть данные о конце послеsrc
поля.Использование awk
Подробнее о моей сети
Мои
ifconfig
шоу, которые у меня естьtun0
для моего VPN иeth0
для моей локальной сети.источник
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
дал мне10.1.2.3 uid 1002
. Поэтому я добавляю в приложение,| awk '{print $1}'
чтобы сохранить только IP-адрес.На FreeBSD вы можете использовать
Это может работать для других сред, в зависимости от вашей настройки.
источник
/etc/resolv.conf
и того, как сетевой маршрутизатор обрабатывает локальные имена хостов. Хорошо использовать это в вашей среде, если вы тестируете это, и оно работает. Но если вы сделаете это, вы создадите «хрупкую» систему, которая вызовет проблемы у других, если вы поделитесь этим. Используйте с осторожностью.Предполагая, что у вас могут быть различные интерфейсы с разными именами, но вам нужен первый не локальный хост и не ipv6, вы можете попробовать:
источник
Я использую этот однострочник:
Использует
ifconfig
(широко доступно), не принимаетlocalhost
адрес, не связывает вас с данным именем интерфейса, не учитывает IPv6 и пытается получить IP-адрес первого доступного сетевого интерфейса.источник
или же
источник
Вы должны использовать
ip
(вместоifconfig
), поскольку он актуален, поддерживается, и, возможно, что наиболее важно для целей написания сценариев, он дает согласованный и анализируемый результат. Ниже приведены несколько похожих подходов:Если вы хотите IPv4-адрес для вашего интерфейса Ethernet
eth0
:Как скрипт:
Результат, полученный выше, находится в нотации CIDR. Если нотация CIDR не нужна, ее можно удалить:
Другой вариант, который IMHO является «наиболее элегантным», - это получение IPv4-адреса для любого интерфейса, используемого для подключения к указанному удаленному хосту (в данном случае 8.8.8.8). Предоставлено @gatoatigrado в этом ответе :
Как скрипт:
Это прекрасно работает на хосте с одним интерфейсом, но более выгодно также на хостах с несколькими интерфейсами и / или спецификациями маршрутов.
ip
был бы мой предпочтительный подход, но это, конечно, не единственный способ снять шкуру с этой кошки. Вот еще один подход, который использует,hostname
если вы предпочитаете что-то более простое / более краткое:Или, если вы хотите адрес IPv6:
источник
Мне нужно было сделать это в псевдониме, чтобы запустить радиосервер на моем проводном сетевом адаптере. я использовал
источник
egrep
амортизируется Используйтеgrep -E
вместо этого.Некоторые команды работают с Centos 6 или 7, команда ниже работает на обоих,
источник
grep | awk | awk
. линия может быть сокращена до/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Предполагая, что вам нужен ваш основной публичный IP-адрес, как это видно из остального мира , попробуйте любой из них:
источник
Этот фрагмент позволяет избежать жесткого кодирования имени устройства (например, «eth0») и будет использовать
ip
вместоifconfig
:Он вернет IP-адрес первого активного устройства, указанного в выходных данных
ip addr
. В зависимости от вашей машины это может быть адрес ipv4 или ipv6.Чтобы сохранить его в переменной, используйте:
источник
все решения, использующие awk / sed / grep, кажутся слишком сложными и уродливыми для моей ситуации ... поэтому я придумала это действительно простое решение, но остерегайтесь, потому что оно делает некоторые предположения, а именно предположение, что интерфейс LAST - это то, что вы интересно. если вы в порядке с этим, то это довольно чисто:
ifconfig | awk '/net / { x = $2 } END { print x }'
в противном случае вы можете сделать какое-нибудь глупое
if
утверждение, чтобы проверить определенный префикс или любые другие критерии, которые у вас могут быть.источник
Простая команда для точного IP-адреса с интерфейсом по умолчанию.
Протестировано на всех ОС Unix
источник
Возможно, это не самое надежное или правильное решение, но в отличие от большинства других решений, команда работает как на Linux, так и на Mac (BSD).
источник
Если вы ищете публичный IP-адрес коробки , вы можете использовать следующее:
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
Вы можете использовать
dig(1)
параметры, такие как-4
или,-6
чтобы специально искать адреса IPv4 или IPv6; Google предоставит ответ в виде записи такогоTXT
типа, в которой будут указаны кавычки, когда они представленыdig
; если вы хотите впоследствии использовать переменную с такими утилитами, какtraceroute
, вы должны использовать что-то вроде tr (1) для удаления указанных кавычек.Другие варианты включают
whoami.akamai.net
иmyip.opendns.com
, которые отвечаютA
иAAAA
записывают (а неTXT
как в приведенном выше примере от Google), поэтому они не требуют удаления кавычек:dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short
dig -4 @resolver1.opendns.com -t any myip.opendns.com +short
dig -6 @resolver1.opendns.com -t any myip.opendns.com +short
Вот пример сценария, который использует все параметры выше для установки переменных:
Если вы ищете частный IP - адрес, или для набора всех IP - адресов , назначенных к ящику, вы могли бы использовать некоторую комбинацию
ifconfig
(на BSD и GNU / Linux),ip addr
(на GNU / Linux),hostname
(варианты-i
и-I
на GNU / Linux) иnetstat
посмотреть, что происходит.источник
это будет делать все, что вы хотите
источник
hostname: invalid option -- 'l'
...