ip addr в одной строке на интерфейс

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

Я хотел бы напечатать конкретную информацию о сетевой конфигурации для различных интерфейсов на всех серверах, которыми я управляю:

  • имя интерфейса
  • ipv4 адрес интерфейса
  • аппаратный mac адрес интерфейса

К сожалению, простой ip -o addr show не позволяет легко распарсить его вывод с помощью awk из-за разрывов строк.

Можно ли сделать так, чтобы ip addr show выводило точно одну строку на интерфейс?

Или можно ли добиться такого же результата с помощью awk и/или sed? Это выходит за пределы моих знаний о этих двух командах, так как строки должны быть сконкатенированы дерево за деревом…

Просто используйте флаг –brief.

ip --brief address show

Новые версии ip могут выводить данные в формате JSON с опцией -j, которые затем можно обработать с помощью фильтра, например jq. Например, вот как можно вывести IPv4 адрес на интерфейсе eth0:

$ ip -j addr show dev eth0 | jq -r '.[0].addr_info | map(select(.family == "inet"))[0].local'
192.168.0.1

Или чтобы получить список всех IPv4 адресов на компьютере, по одному в строке:

ip -j addr show | jq -r 'map(.addr_info) | map(map(select(.family == "inet").local)) | flatten | .[]'
127.0.0.1
192.168.0.1
172.19.0.1
172.17.0.1
172.18.0.1

Удалите select(...), чтобы включить IPv6, например. Возможно много других вариаций.

Существует ip -o addr show, но он выводит меньше информации.

Вот способ преобразовать вывод ip addr show в одну строку на интерфейс. Напечатать новую строку перед началом каждого интерфейса, кроме первой строки; затем напечатать содержимое строки; напечатать новую строку в конце файла.

ip addr show |
awk '/^[^ ]/ && NR!=1 {print ""}
     {printf "%s", $0}
     END {print ""}'
sed  -nE  '/^[0-9]/! {H;$!d}     # аккумулировать завершающие строки
           x                     # обмен новой ведущей строки на накопленный пучок
           s/[^ ]* ([^ ]*).* link\/[^ ]* ([^ ]*).* inet ([^ ]*).*/\1\t\3\t\2/p'

и замена довольно прямолинейная, идентифицирует и красиво выводит 2-е слово, слово после link/anything, слово после inet

Этот скрипт gawk распарсит ip addr show и предоставит запрошенную информацию. Несколько IPv4 адресов соединены запятой

ip a | awk 'function outline() {if (link>"") {printf "%s %s %s\n", iface, inets, link}} $0 ~ /^[1-9]/ {outline(); iface=substr($2, 1, index($2,":")-1); inets=""; link=""} $1 == "link/ether" {link=$2} $1 == "inet" {inet=substr($2, 1, index($2,"https://unix.stackexchange.com/")-1); if (inets>"") inets=inets ","; inets=inets inet} END {outline()}'

Выделение для чтения:

ip addr show |
    awk '
        # Функция вывода для форматирования результатов (если есть)
        function outline() {
            if (link>"") {printf "%s %s %s\n", iface, inets, link}
        }

        # Секция интерфейса начинается здесь
        $0 ~ /^[1-9]/ {
            outline();                              # Вывести все, что раньше коллекционировали
            iface=substr($2, 1, index($2,":")-1);   # Захватить имя интерфейса
            inets="";                               # Очистить список адресов
            link=""                                 # и MAC тоже
        }

        # Захватить MAC
        $1 == "link/ether" {
            link=$2                   
        }

        # Захватить IPv4 адрес. Конкатенировать с предыдущими с запятой
        $1 == "inet" {
            inet=substr($2, 1, index($2,"https://unix.stackexchange.com/")-1);    # Отбросить /nn маску подсети
            if (inets>"") inets=inets ",";          # Добавить к существующему списку запятую
            inets=inets inet                        # Добавить этот IPv4
        }

        # Ввод обработан
        END {
            outline()                               # Вывести оставшуюся коллекцию
        }
    '

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

eth0 10.0.2.15 08:00:27:0f:db:b3
eth1 192.168.56.101 08:00:27:33:04:26

на debian:

man ip
...
       -o, -oneline
              выводит каждую запись на одной строке, заменяя переносы строк на символ '\'. Это удобно, когда нужно посчитать записи с помощью wc(1) или grep(1) в выводе.

[email protected] так как я ранее неправильно истолковал вопрос.

Попробуйте это:

ip addr show|xargs|sed 's/ \([0-9]*: \)/\n\1/g'

Каждая запись адаптера начинается с [0-9]*: , что может быть вашим разделителем:

root@jprst0202:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.7.11.1/24 brd 10.7.11.255 scope global tun0
       valid_lft forever preferred_lft forever
4: tun1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.7.5.1/24 brd 10.7.5.255 scope global tun1
       valid_lft forever preferred_lft forever
...

Итак:

  • xargs – всё на одну строку
  • sed… – добавляется новая строка перед каждым пробелом,числом (или множеством), двоеточием и снова пробел паттерн

Результат:

root@jprst0202:~# ip addr show|xargs|sed 's/ \([0-9]*: \)/\n\1/g'
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
2: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.7.11.1/24 brd 10.7.11.255 scope global tun0 valid_lft forever preferred_lft forever
4: tun1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.7.5.1/24 brd 10.7.5.255 scope global tun1 valid_lft forever preferred_lft forever
5: tun2: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/none inet 10.7.7.1/24 brd 10.7.7.255 scope global tun2 valid_lft forever preferred_lft forever
...

Используйте команду ip -br a

❯ ip -br a
lo               UNKNOWN        127.0.0.1/8 ::1/128
eno1             UP             fe80::1e1b:dff:fe9c:59be/64
eno2             DOWN
enp193s0f0       UP             fe80::92e2:baff:fe18:9e64/64
enp193s0f1       UP
br-mgmt          UP             10.1.1.11/24
lxcbr0           DOWN           10.100.0.1/24
virbr0           DOWN           192.168.122.1/24
virbr1           UP             192.168.121.1/24
vnet0            UNKNOWN        fe80::fc54:ff:fe68:63cb/64
vnet1            UNKNOWN        fe80::fc54:ff:fe41:8608/64
docker0          DOWN           172.17.0.1/16 2001:db8:1::1/64 fe80::42:92ff:fe5d:ea35/64 fe80::1/64
br-5437536a1d09  DOWN           10.10.0.1/16

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

Когда речь заходит о вычислении конфигураций сетевых интерфейсов на ваших серверах, инструментарий, такой как ip addr, играет ключевую роль. Понимание и умение интерпретировать его вывод — это основная задача для IT специалистов, поскольку она позволяет глубже оценить сетевые параметры и выявить возможные проблемы.

Теория
Первое, что нужно понять — это предназначение команды ip addr. Этот инструмент используется для отображения или манипуляции с IP-адресами устройств в сети. Он предоставляет исчерпывающую информацию о каждом сетевом интерфейсе на вашем сервере, включая имя интерфейса, его IP-адрес (как IPv4, так и IPv6), MAC-адрес и другие атрибуты.

Пример
Рассмотрим типичную задачу: вам необходимо отобразить информацию о сетевых интерфейсах в формате одной строки на интерфейс. Это позволит более эффективно обрабатывать данные с помощью других инструментов, таких как awk или sed, применяя их для дальнейшего анализа или обработки.

Реализация
Самый простой способ получить краткий вывод с каждой строкой, представляющей отдельный интерфейс, — это использовать флаг -o (или --oneline) с ip addr. Это обеспечивает вывод, где каждая запись представлена в одной строке:

ip -o addr show

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

  1. Использование флага -j для вывода в формате JSON
    Новые версии ip поддерживают вывод в формате JSON при использовании флага -j. Это позволяет легко обрабатывать данные с помощью jq, который предоставляет гибкость при извлечении нужной информации:

    ip -j addr show | jq -r '.[] | "\(.ifname) \(.addr_info[]? | select(.family=="inet") | .local) \(.link_info?.address)"'

    В этом примере вы извлекаете имя интерфейса, IPv4-адрес и MAC-адрес для каждого интерфейса.

  2. Использование awk для преобразования вывода
    В случаях, когда необходимо более глубоко обработать вывод ip addr, вы можете использовать awk:

    ip addr show | awk '
    function output() {if (iface != "") {printf "%s %s %s\n", iface, inet, mac}}
    /^[0-9]+:/ {output(); iface=$2; inet=""; mac=""}
    /link\/ether/ {mac=$2}
    /inet / {inet=inet $2 " "}
    END {output()}'

    Этот скрипт захватывает имя интерфейса, его MAC-адрес и IPv4-адрес.

  3. Обработка вывода с помощью sed
    Альтернативно, sed может быть использован для предварительной обработки и выравнивания строк:

    ip addr show | sed -nE '/^[0-9]/!{H;$!d}; x; s/^ //; s/^([0-9]+: )([a-zA-Z0-9]+):.* link\/[^ ]+ ([^ ]+).* inet ([^ ]+).*/\2 \4 \3/p'

    Этот скрипт упрощает вывод, сохраняя ключевые элементы.

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

Заключение
В современной ИТ-среде важно уметь выбирать подходящие инструменты для анализа и управления системами. Способность адаптировать и обрабатывать вывод командных утилит, таких как ip addr, с применением awk, sed или jq, позволяет не просто следить за состоянием системы, но и активно управлять ею. Это навык, который значительно увеличивает производительность вашего ИТ-менеджмента и позволяет более стратегически подходить к вопросам сетевой архитектуры и безопасности.

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

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