Назад | Перейти на главную страницу

Как получить таблицы маршрутизации в формате JSON (linux)?

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

Список всех адресов: ip --json address show

[{ ... },{
    "ifindex": 2,
    "ifname": "eth0",
    "flags": ["BROADCAST","MULTICAST","UP","LOWER_UP"],
    "mtu": 1500,
    "qdisc": "fq_codel",
    "master": "lan0",
    "operstate": "UP",
    "group": "default",
    "txqlen": 1000,
    "link_type": "ether",
    "address": "44:89:3f:e9:a8:08",
    "broadcast": "ff:ff:ff:ff:ff:ff",
    "addr_info": []
},{ ... }]



Список интерфейсов: ip --json link show

[{ ... },{
    "ifindex": 2,
    "ifname": "eth0",
    "flags": ["BROADCAST","MULTICAST","UP","LOWER_UP"],
    "mtu": 1500,
    "qdisc": "fq_codel",
    "master": "lan0",
    "operstate": "UP",
    "linkmode": "DEFAULT",
    "group": "default",
    "txqlen": 1000,
    "link_type": "ether",
    "address": "44:89:3f:e9:a8:08",
    "broadcast": "ff:ff:ff:ff:ff:ff"
},{ ... }]



Я ожидал также получить список маршрутов в JSON, но мне удалось получить только его версию в виде открытого текста:
Список маршрутов: ip --json route list (это все еще в виде открытого текста)

1.1.1.2 via 192.168.255.11 dev lan0 table hopper src 192.168.254.1 metric 10
default via 10.19.1.4 dev wg0 metric 5
default via 192.168.255.11 dev lan0 metric 6
10.19.1.0/24 dev wg0 scope link
124.214.110.113 via 192.168.255.11 dev lan0 metric 4
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-fea43fdf31f1 proto kernel scope link src 172.18.0.1
172.19.0.0/16 dev br-6f9e681d15b0 proto kernel scope link src 172.19.0.1 linkdown
192.168.0.0/16 dev lan0 proto kernel scope link src 192.168.254.1
192.168.1.0/24 dev wan0 proto kernel scope link src 192.168.1.9
192.168.1.0/24 via 192.168.255.11 dev lan0 metric 3
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
multicast 239.255.255.250/32 from 192.168.1.109/32 table default proto 17 unresolved

Поскольку я нигде не мог найти решения, я отвечу на свой вопрос и оставлю здесь то, что сделал.
Кто знает, может, когда-нибудь он мне снова понадобится, а может быть, у кого-то будет такая же проблема! :-)

Итак, вот что я сделал.
Я использовал команду jq разобрать результат ip route list table all используя регулярное выражение, преобразуя вывод в JSON.
Не стесняйтесь играть с jq, и нажмите здесь, чтобы использовать онлайн-песочницу уже загружен с этим решением.
Это полная команда:

ip route list table all | jq --raw-input --slurp 'split("\n") | map(capture("^(?:(?<broadcast>broadcast) ?)?(?:(?<local>local) ?)?(?:(?<multicast>multicast) ?)?(?: ?(?<network>.*?) )(?:from (?<from>\\S+) ?)?(?:via (?<via>\\S+) ?)?(?:dev (?<dev>\\S+) ?)?(?:table (?<table>\\S+) ?)?(?:proto (?<proto>\\S+) ?)?(?:scope (?<scope>\\S+) ?)?(?:src (?<src>\\S+) ?)?(?:metric (?<metric>\\d+) ?)?(?<linkdown>linkdown)?(?<unresolved>unresolved)?"; "g"))'

И вот результат:

[
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "1.1.1.2",
    "from": null,
    "via": "192.168.255.11",
    "dev": "lan0",
    "table": "hopper",
    "proto": null,
    "scope": null,
    "src": "192.168.254.1",
    "metric": "10",
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "default",
    "from": null,
    "via": "10.19.1.4",
    "dev": "wg0",
    "table": null,
    "proto": null,
    "scope": null,
    "src": null,
    "metric": "5",
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "default",
    "from": null,
    "via": "192.168.255.11",
    "dev": "lan0",
    "table": null,
    "proto": null,
    "scope": null,
    "src": null,
    "metric": "6",
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "10.19.1.0/24",
    "from": null,
    "via": null,
    "dev": "wg0",
    "table": null,
    "proto": null,
    "scope": "link",
    "src": null,
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "124.214.110.113",
    "from": null,
    "via": "192.168.255.11",
    "dev": "lan0",
    "table": null,
    "proto": null,
    "scope": null,
    "src": null,
    "metric": "4",
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "172.17.0.0/16",
    "from": null,
    "via": null,
    "dev": "docker0",
    "table": null,
    "proto": "kernel",
    "scope": "link",
    "src": "172.17.0.1",
    "metric": null,
    "linkdown": "linkdown",
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "172.18.0.0/16",
    "from": null,
    "via": null,
    "dev": "br-fea43fdf31f1",
    "table": null,
    "proto": "kernel",
    "scope": "link",
    "src": "172.18.0.1",
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "172.19.0.0/16",
    "from": null,
    "via": null,
    "dev": "br-6f9e681d15b0",
    "table": null,
    "proto": "kernel",
    "scope": "link",
    "src": "172.19.0.1",
    "metric": null,
    "linkdown": "linkdown",
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "192.168.0.0/16",
    "from": null,
    "via": null,
    "dev": "lan0",
    "table": null,
    "proto": "kernel",
    "scope": "link",
    "src": "192.168.254.1",
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "192.168.1.0/24",
    "from": null,
    "via": null,
    "dev": "wan0",
    "table": null,
    "proto": "kernel",
    "scope": "link",
    "src": "192.168.1.9",
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": null,
    "network": "192.168.1.0/24",
    "from": null,
    "via": "192.168.255.11",
    "dev": "lan0",
    "table": null,
    "proto": null,
    "scope": null,
    "src": null,
    "metric": "3",
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": "broadcast",
    "local": null,
    "multicast": null,
    "network": "127.0.0.0",
    "from": null,
    "via": null,
    "dev": "lo",
    "table": "local",
    "proto": "kernel",
    "scope": "link",
    "src": "127.0.0.1",
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": "local",
    "multicast": null,
    "network": "127.0.0.1",
    "from": null,
    "via": null,
    "dev": "lo",
    "table": "local",
    "proto": "kernel",
    "scope": "host",
    "src": "127.0.0.1",
    "metric": null,
    "linkdown": null,
    "unresolved": null
  },
  {
    "broadcast": null,
    "local": null,
    "multicast": "multicast",
    "network": "239.255.255.250/32",
    "from": "192.168.1.109/32",
    "via": null,
    "dev": null,
    "table": "default",
    "proto": "17",
    "scope": null,
    "src": null,
    "metric": null,
    "linkdown": null,
    "unresolved": "unresolved"
  }
]

Этого уже достаточно для того, что мне было нужно, но, если у вас есть свободное время, все еще есть возможности для улучшения: все нулевые значения могут быть удалены, «метрические» значения могут быть преобразованы в числа, а «широковещательный», «локальный» , "multicast", "linkdown" и "unresolved" могут быть логическими.