Linux/bash: Как получить IPv6-адрес интерфейса?

Вопрос или проблема

Какую команду я могу использовать, чтобы получить IPv6-адрес интерфейса в скрипте?

Обновление: Вывод sed из одного из ответов.

$ ip -6 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 fe80::224:d7ff:fed0:4f5c/64 scope link 
       valid_lft forever preferred_lft forever

Другой:

$ ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'
$ ip addr show dev eth0
  2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
  link/ether f0:de:f1:7b:e9:6c brd ff:ff:ff:ff:ff:ff

Вы могли бы использовать:

ip -6 addr

Это вернет все IPv6-адреса, которые у вас настроены.

Существует множество способов сделать это.

Вот один из них:

ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'

Это похоже на ответ Роберта, за исключением того, что он только извлекает адрес.

Если вы используете Linux, вы также можете распарсить:
/proc/net/if_inet6

Первая колонка – это полный IPv6 без двоеточий.
Шестая колонка – это имя интерфейса.

Вот довольно длинный неоптимизированный вариант (я знаю только основы awk). Возможно, лучше выбрать python/perl.

for i in "$(grep enp0s25 /proc/net/if_inet6)"; do
    echo "$i" | awk '{
        split($1, _, "[0-9a-f]{,4}", seps)
        joined = sep = ""
        for (i=1; i in seps; i++) {
            joined = joined sep seps[i]
            sep = ":"
        }
        print joined
    }'
done

Если у вас есть GNU awk (gawk), это можно сократить до:

for i in "$(grep enp0s25 /proc/net/if_inet6)"; do
    echo "$i" | gawk '@include "join"
    {
        split($1, _, "[0-9a-f]{,4}", seps)
        print join(seps, 1, length(seps), ":")
    }'
done

Вы можете поместить это в функцию {ba,z,}sh для использования позже.

Другие упомянутые здесь подходы НЕ СРАБОТАЮТ, если интерфейс не называется eth0. В мире SystemD, имена интерфейсов далеко не предсказуемы, так как конвенции именования интерфейсов изменились кардинально

Мой подход, наоборот, находит и извлекает Глобальный уникальный адрес – каким бы ни было имя интерфейса. IPv6-адрес может быть настроен для wlan0 или любого другого имени, и мой bash-скрипт успешно извлечет и развернет его как переменную в конфигурационном файле, требующем указания слушающего адреса.

IPV6GLOBALUNICAST="$(ip -6 addr|awk '{print $2}'|grep -P '^(?!fe80)[[:alnum:]]{4}:.*/64'|cut -d "https://superuser.com/" -f1)"

Вставьте следующее в командную строку хоста с настроенным IPv6-адресом, чтобы протестировать это:

ip -6 addr|awk '{print $2}'|grep -P '^(?!fe80)[[:alnum:]]{4}:.*/64'|cut -d "https://superuser.com/" -f1

Замените (?!fe80) на (?!f), чтобы исключить не только адреса локальной связи, но и не глобально роутируемые локальные уникальные адреса.

Я использую это с большим успехом, и это ни разу не подвело в любых условиях. Надеюсь, это поможет – Terrence Houlahan

.

Ответ или решение

Для получения IPv6-адреса интерфейса в Linux существует несколько подходов, которые могут применяться в скриптах. Каждый из них имеет свои достоинства и недостатки, а также специфические особенности использования. Основная задача заключается в извлечении нужного адреса из списка всех доступных на устройстве адресов. Рассмотрим наиболее распространенные способы получения этой информации, включая использование утилит командной строки и обработки вывода.

Теория

IPv6-адреса — это современный стандарт IP-адресации, который обеспечивает гораздо больший объем адресного пространства по сравнению с IPv4. Они состоят из 128 бит, разделенных на восемь групп шестнадцатеричных чисел, и часто ассоциируются с интерфейсами сетевых устройств для установления сетевых соединений.

Основным инструментом для работы с сетевыми настройками в Linux является утилита ip, которая предоставляет мощный способ управления интерфейсами, адресами и маршрутами. Чтобы получить список IPv6-адресов текущих интерфейсов, можно использовать команду:

ip -6 addr

Пример

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

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 fe80::224:d7ff:fed0:4f5c/64 scope link 
       valid_lft forever preferred_lft forever

Для извлечения IPv6-адреса конкретного интерфейса, например eth0, можно использовать следующую команду с помощью sed:

ip addr show dev eth0 | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'

Эта команда обрабатывает вывод ip addr show dev eth0, выделяя только строку с IPv6-адресом и удаляя все лишнее.

Применение

Иногда может понадобиться более общий подход, который будет работать независимо от имени интерфейса. В современном Linux, благодаря изменению подходов к именованию интерфейсов (например, в SystemD), интерфейсы могут иметь непредсказуемые имена.

Для более универсального подхода можно использовать следующий однострочник на awk:

ip -6 addr | awk '{print $2}' | grep -P '^(?!fe80)[[:alnum:]]{4}:.*/64' | cut -d "/" -f1

Этот метод извлекает все не локальные адреса (кроме адресов, начинающихся с fe80, которые представляют собой link-local адреса) и выводит их в сокращенном виде. Если вы хотите исключить и уникальные локальные адреса (ULA), начинающиеся с fc00 или fd00, замените (?!fe80) на (?!f) в условии регулярного выражения.

Кроме того, можно воспользоваться информацией из /proc/net/if_inet6, где хранится информация об интерфейсах и их адресах. Например:

for i in "$(grep enp0s25 /proc/net/if_inet6)"; do
    echo "$i" | awk '{
        split($1, _, "[0-9a-f]{,4}", seps)
        joined = sep = ""
        for (i=1; i in seps; i++) {
            joined = joined sep seps[i]
            sep = ":"
        }
        print joined
    }'
done

Это пример использования awk для разбора данных из /proc/net/if_inet6 с последующей обработкой для получения читаемого формата IPv6-адреса.

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

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

Оцените материал
Добавить комментарий

Капча загружается...