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

В статье же речь пойдет о том, чего ощутимо не хватает современным системам Linux с точки зрения этой философии, а также будет предложено решение связанных с этим проблем.

Впервые философия Unix была официально сформулирована в предисловии к научному журналу Bell Systems Technical Journal 1978 года, где описывалась система с разделением времени:


Предисловие к Bell System Technical Journal

Среди создателей и пользователей системы Unix выработался особый набор принципов, описывающий и продвигающий ее отличительный стиль:

(i) Добиваться от одной программы эффективного выполнения одной задачи. Для реализации других лучше создать отдельную программу, чем нагружать новыми «возможностями» старые.

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

(iii) Проектировать и создавать программы, в том числе операционные системы, с возможностью раннего тестирования, желательно в течение нескольких недель. Не сомневаясь отбрасывать все непроработанные элементы и заново их переделывать.

(iv) Предпочитать неквалифицированной помощи использование инструментов, чтобы…

Пункты i и ii часто повторяются в современном мире разработки, и неспроста. Но теперь пришло время перенести эту философию в 21 век, определив стандартный формат вывода для не интерактивного использования.

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

$ ifconfig ens33 | grep inet | awk '{print $2}' | cut -d/ -f1 | head -n 1

Совсем не радует глаз.

Примерно до 2013 года считалось, что неструктурированный текст является хорошим способом вывода данных в командной строке. В Unix/Linux есть много инструментов парсинга текста, таких как sed, awk, grep, tr, cut, rev и так далее, которые можно объединить в конвейер для переформатирования нужных данных перед их отправкой следующей программе.

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

Однако в 2013 году появился конкретный формат данных, получивший название JSON, который сначала был стандартизирован как ECMA-404, а позднее в 2017 году как RFC 8259 и ISO/IEC 21778:2017. На сегодня JSON повсеместно встречается в REST API и используется для сериализации всего, начиная с данных между приложениями до индикаторов компрометации в спецификации STIX2 и заканчивая файлами конфигурации.

Во всех современных языках присутствуют библиотеки JSON и даже инструменты парсинга этого формата для командной строки, например jq. JSON повсюду. Его легко использовать, и он является стандартом.

Если бы JSON существовал в 1970 году, когда я только родился, то Кен Томпсон и Деннис Ричи вполне могли бы определить его в качестве рекомендованного формата вывода, чтобы помочь программам в конвейере «выполнять эффективно одну задачу».

В этой связи, я утверждаю, что Linux и все его поддерживаемые GNU и не GNU утилиты должны предоставлять вариант вывода JSON. Мы уже наблюдаем ограниченную поддержку этого в тех же утилитах systemctl или ip, где на выходе этот формат можно получить через опцию -j.

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

Примеры ниже:

Вот ip addr с выводом JSON:

$ ip -j addr show dev ens33
[{
"addr_info": [{},{}]
},{
"ifindex": 2,
"ifname": "ens33",
"flags": ["BROADCAST","MULTICAST","UP","LOWER_UP"],
"mtu": 1500,
"qdisc": "fq_codel",
"operstate": "UP",
"group": "default",
"txqlen": 1000,
"link_type": "ether",
"address": "00:0c:29:99:45:17",
"broadcast": "ff:ff:ff:ff:ff:ff",
"addr_info": [{
"family": "inet",
"local": "192.168.71.131",
"prefixlen": 24,
"broadcast": "192.168.71.255",
"scope": "global",
"dynamic": true,
"label": "ens33",
"valid_life_time": 1732,
"preferred_life_time": 1732
},{
"family": "inet6",
"local": "fe80::20c:29ff:fe99:4517",
"prefixlen": 64,
"scope": "link",
"valid_life_time": 4294967295,
"preferred_life_time": 4294967295
}]
}
]

А вот ip route, не выводящий JSON, даже с флагом -j:

$ ip -j route
default via 192.168.71.2 dev ens33 proto dhcp src 192.168.71.131 metric 100 
192.168.71.0/24 dev ens33 proto kernel scope link src 192.168.71.131 
192.168.71.2 dev ens33 proto dhcp scope link src 192.168.71.131 metric 100

Некоторые другие более современные инструменты вроде kubectl и aws-cli предлагают более согласованные варианты вывода JSON, упрощая парсинг и составление конвейера.

Но есть и много старых инструментов, которые до сих пор выводят практически недоступный для парсинга текст (например, netstat, lsblk, ifconfig, iptables и т.д.).

Интересно, что в Windows PowerShell реализовали использование структурированных данных, что является хорошим примером, на котором сообщество Linux может поучиться.

Предложения по решению


Решением будет вернуться ко всем GNU и не-GNU легаси-утилитам командной строки, выводящим текстовые данные, и добавить к ним вариант вывода JSON. Все API операционной системы, такие как /proc и /sys, должны сериализовывать свои файлы в JSON или передавать данные альтернативному API, выводящему их в этом формате.


github.com/kellyjonbrazil/jc

Тем временем я написал инструмент под названием jc, который конвертирует вывод десятков как GNU, так и не GNU команд, а также файлов конфигурации в JSON.

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

Попробуйте его онлайн демоверсию.

Этот инструмент, в том числе, доступен в качестве плагина-фильтра для Ansible.

JC в действии


Ниже я продемонстрирую, как jc может упростить нам жизнь, пока GNU/Linux не привнесут философию Unix в реалии 21 века. Возьмем тот же пример с получением IP-адреса из сети Ethernet:

$ ifconfig ens33 | grep inet | awk '{print $2}' | cut -d/ -f1 | head -n 1
192.168.71.138

А вот, как то же самое делается с помощью jc и инструмента парсинга вроде jq:

$ ifconfig ens33 | jc --ifconfig | jq -r '.[].ipv4_addr'
192.168.71.138

Либо:

$ jc ifconfig ens33 | jq -r '.[].ipv4_addr'
192.168.71.138

Вот еще один пример перечисления прослушиваемых TCP-портов системы:

$ netstat -tln | tr -s ' ' | cut -d ' ' -f 4 | rev | cut -d : -f 1 | rev | tail -n +3
25
22

Очень много текста для простого получения портов. Вот то же самое, но с использованием jc и jq:

$ netstat -tln | jc --netstat | jq '.[].local_port_num'
25
22

Либо:

$ jc netstat -tln | jq '.[].local_port_num'
25
22

Обратите внимание, насколько более интуитивны поиск и сравнение семантически-улучшенных структурированных данных относительно неудобного парсинга низкоуровневого текста.

Кроме того, вывод JSON можно сохранить для использования любым языком высокого уровня вроде Python или JavaScript без парсинга командной строки. Это наше будущее, друзья!

Сейчас jc поддерживает следующие парсеры: arp, df, dig, env, free, /etc/fstab, history, /etc/hosts, ifconfig, iptables, jobs, ls, lsblk, lsmod, lsof, mount, netstat, ps, route, ss, stat, systemctl, systemctl list-jobs, systemctl list-sockets, systemctl list-unit-files, uname -a, uptime и w.

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

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

Комментарии (87)


  1. rcl
    29.08.2021 17:29
    +10

    До json популярным был формат xml. Однако сообщество не торопилось принимать на вооружение xml для передачи данных через потоки ввода/вывода. Может и сейчас не стоит торопиться нагружать код всех утилит генераторами и парсерами json?

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

    lsblk(1).


    1. lain8dono
      29.08.2021 17:58
      +14

      Что json, что xml, оба так себе подходят для потоковой передачи. Точнее совсем никак не подходят. Хотя костыли есть.


      1. akurilov
        29.08.2021 19:07
        +3

        Конечно, должно быть все в Yaml


        1. MrRitm
          01.09.2021 12:46

          Вы не правы, как и все в интернете! CSV спасёт отца русской демократии! :-)


      1. DistortNeo
        29.08.2021 19:36
        +1

        Далеко не всегда имеется смысл в именно потоковой передаче.
        Опять же, ничто не мешает передавать ответ не одним json-ом, а несколькими, каждый в отдельной строке.


        1. sshikov
          29.08.2021 20:04
          +4

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

          Ну да, не всегда. Но чаще чем кажется. И бенефиты дает дополнительные.


        1. edo1h
          29.08.2021 20:33
          +10

          Далеко не всегда имеется смысл в именно потоковой передаче.

          понимаете в чём проблема, сегодня вы делаете некий формат, который должен заменить текст. завтра вам придётся вдруг передать от процесса к процессу больше информации, чем помещается в ОП, а утилиты будут уже использовать этот формат.
          у grep/sed/awk и прочих олдскульных утилит нет проблем с обработкой гигантских потоков данных, а с xml/json будут.


          1. easyman
            29.08.2021 21:44

            Вы в курсе sax xml? Именно, для потоков и никаких проблем


            1. edo1h
              29.08.2021 21:55
              +1

              да, в курсе. но ведь нет гарантий, что он всеми будет использоваться.


              P. S. я не пытаюсь сказать, что plain text — наше всё и пытающиеся придумать что-то другое должны быть сожжены за ересь. я лишь говорю, что надо хорошенько подумать. картинку про новый стандарт все помнят, думаю.


              1. illiakailli
                01.09.2021 03:49

                А вот помогите дураку, почему нельзя передавать какой-нибудь https://en.wikipedia.org/wiki/Media_type а потом blob этого типа? Есть уже наверное такой мета-стандарт передачи ... в интернете используется ) Потоковая передача - кушаем blob пока не встретится следующий media type заголовок. Ну это я от фонаря сморозил, наверняка много-более-ученые умы об этом уже чесались как-то особо правильно ...


                1. edo1h
                  01.09.2021 16:03

                  ну хотя бы потому, что хочется сохранить человекочитаемость.
                  конечно, она может быть сохранена и с блобами, но уже потребуется некоторая инфраструктура.


                  1. illiakailli
                    02.09.2021 00:24

                    Так ведь blob может быть человекочитаемый, зависит от формата того, что в нем содержится. Инфраструктура всегда требуется, не очень понял что вы имеете в виду.


      1. blind_oracle
        30.08.2021 10:46
        +2

        Если нужен поток объектов JSON то просто закрываешь один и открываешь другой. В том же Go json.Decoder парсит такой поток из коробки.

        А если нужно передать просто большой объект то тут уже да, только атомарно.

        Но те же проблемы и с обычным текстом, когда для парсинга необходим контекст из предыдущих строк.


    1. olehorg
      29.08.2021 21:31
      +2

      а до xml народ не сомневался что csv вполне покрывает все возможные потребности (правда, csv настолько мало отличался от вывода unix что никому в голову не приходило менять шило на мыло)


    1. fishHook
      30.08.2021 11:47
      +1

      А ведь нет никакой проблемы сконвертировать XML в JSON. Возьмите любой формат структурированных данных и вы скорее всего без потерь транслируете его в другой формат. Если у вас есть middleware слой, который понимает в каком формате поступают данные (ну тот же шебанг, это же юникс-вей, правильно?) и в каком они ожидаются на входе другого процесса, то для функционирования системы достаточно иметь парсеры соответствующих форматов. Какие проблемы?

      Однако сообщество не торопилось принимать на вооружение xml для передачи данных через потоки ввода/вывода.

      Ну и плохо. Добавление нового не означает ведь отказ от старого. Никто же отбирает старый добрый плоский текст, и в этом смысле для меня непонятна инерция сообщества. «Не торопились», это скорее всего вопрос мотивации, а не целесообразности. А тут вскрывается более глубокая проблема юникса — отсутствие руководящей политики партии и множественность конкурирующих решений, которые порой придумываются абы только не так как у других.


      1. rcl
        30.08.2021 12:02

        "Не торопились" но двигались. Вот вам пример: Subversion предусматриала вывод в XML формате. Однако в массах XML-вывод остался не востребован.


      1. mikhailian
        30.08.2021 14:15
        +4

        А ведь нет никакой проблемы сконвертировать XML в JSON.

        А как конвертировать пространства имён? а элементы и атрибуты? Да даже ограничения на символы, что с ними делать?

        Нет никакой проблемы сконвертировать в одну сторону, хотя дело это не такое простое, как кажется на первый взгляд. А вот туда-обратно... начинаются проблемы.


        1. fishHook
          30.08.2021 14:43
          -2

          <h:table xmlns:h="http://www.w3.org/TR/html4/">
          <h:tr>
          <h:td>Яблоки</h:td>
          <h:td>Бананы</h:td>
          </h:tr>
          </h:table>

          <f:table xmlns:f="http://www.w3schools.com/furniture">
          <f:name>Африканский кофейный столик</f:name>
          <f:width>80</f:width>
          <f:length>120</f:length>
          </f:table>



          {
          "root": {
          "h:table": {
          "-xmlns:h": "http://www.w3.org/TR/html4/",
          "h:tr": {
          "h:td": [
          "Яблоки",
          "Бананы"
          ]
          }
          },
          "f:table": {
          "-xmlns:f": "http://www.w3schools.com/furniture",
          "f:name": "Африканский кофейный столик",
          "f:width": "80",
          "f:length": "120"
          }
          },
          }


          1. nin-jin
            30.08.2021 15:17
            +2

            Автоматизированная тулза кушающая произвольный XML вам такой JSON не выдаст. А даже если вы и навставляете костылей, чтобы генерировалось именно это - обрабатывать такой JSON будет настоящим адом, ибо малейшее изменение XML будет серьёзно менять структуру JSON.


            1. fishHook
              30.08.2021 16:02

              я, собственно, автоматизированную тулзу и изал
              https://www.utilities-online.info/xmltojson


            1. fishHook
              30.08.2021 16:07

              ибо малейшее изменение XML будет серьёзно менять структуру JSON

              покажите пример, как малейшее изменение в XML приводит к серьезным изменениям в JSON


              1. nin-jin
                30.08.2021 16:16
                +3

                <h:table xmlns:h="http://www.w3.org/TR/html4/">
                <h:tr>
                <h:td>Яблоки</h:td>
                <h:td>Бананы</h:td>
                </h:tr>
                </h:table>
                {
                  "h:table": {
                    "-xmlns:h": "http://www.w3.org/TR/html4/",
                    "h:tr": {
                      "h:td": [
                        "Яблоки",
                        "Бананы"
                      ]
                    }
                  },
                  "#omit-xml-declaration": "yes"
                }
                <h:table xmlns:h="http://www.w3.org/TR/html4/">
                <h:tr>
                <h:td>Яблоки</h:td>
                </h:tr>
                </h:table>
                {
                  "h:table": {
                    "-xmlns:h": "http://www.w3.org/TR/html4/",
                    "h:tr": {
                      "h:td": "Яблоки"
                    }
                  },
                  "#omit-xml-declaration": "yes"
                }
                <h:table xmlns:h="http://www.w3.org/TR/html4/">
                <h:tr>
                <h:td>Яблоки<br/></h:td>
                </h:tr>
                </h:table>
                {
                  "h:table": {
                    "-xmlns:h": "http://www.w3.org/TR/html4/",
                    "h:tr": {
                      "h:td": {
                        "#text": "Яблоки",
                        "br": {
                          "-self-closing": "true"
                        }
                      }
                    }
                  },
                  "#omit-xml-declaration": "yes"
                }


                1. fishHook
                  30.08.2021 16:26
                  -6

                  и я не вижу проблемы ни в одном из примеров


                  1. nin-jin
                    30.08.2021 16:30
                    +4

                    Ну что поделать. Когда начнёте писать код обработки этого джейсона - увидите.


        1. DistortNeo
          30.08.2021 23:10

          А зачем, собственно, конвертировать из одного формата в другой? Программа выдала результат в XML — обрабатываете XML. Программа выдала результат в JSON — обрабатываете JSON.


      1. semmaxim
        28.09.2021 11:48
        +1

        XML гораздо богаче, чем JSON. Взять те же комментарии. Так что автоматически любой XML преобразовать в JSON невозможно.


        1. edo1h
          28.09.2021 16:50

          XML гораздо богаче, чем JSON

          ну да, можно сделать


          <computer>
              <motherboard>ASUS XE3</motherboard>
          </computer>

          а можно


          <computer motherboard="ASUS XE3" />


          1. semmaxim
            28.09.2021 21:16
            +1

            Нет. эти xml не эквивалентны. Хотя иногда сериализуются/десериализуются одинаково. А ещё комментарии, пространства имён, CDATA и вагон чего ещё.


            1. edo1h
              29.09.2021 02:46

              Нет. эти xml не эквивалентны

              так про то и речь, видимо, намёк был слишком тонким )


  1. Alex_ME
    29.08.2021 17:33
    +16

    Это еще не совсем XXI век. Лучше строго-типизированное двоичное представление. Отказ от многих вариантов вывода, а использовать отдельные программы для парсинга и вывода (в таблички, в джсон итп). Ой, мы изобрели power shell.


    Но и это ещё не всё. Все эти инструменты командной строки остались в основном в области администрирования либо используются разработчиками под *nix. Большинство пользовательских программ — страшные монолиты. Вот если применить UNIX-way там каким-то образом, то это было бы точно на уровне XXI века.


    1. sshikov
      29.08.2021 20:02

      >страшные монолиты
      Ну почему сразу только страшные и только монолиты? Построение программ из компонентов, которые решают каждый свою задачу, обмениваясь данными по стандартным протоколам… Ой, мы изобрели SOA? Или микросервисы? И таки да, типизированные протоколы обмена, когда компоненты обмениваются не текстом без структуры через пайпы, а типизированными сообщениями скажем через кафку — вот это, вообще говоря, и является типичным для 21 века. И как это сделать из монолита — примерно понятно. Юникс вей правда к этому за уши притягивать не имеет смысла.


    1. maslyaev
      05.09.2021 19:18
      +3

      Личная просьба. А давайте строго-типизированное двоичное представление будет не в XXI, а в XXII веке, чтобы я гарантированно не дожил до этого счастья.


  1. andrew_q
    29.08.2021 17:55
    +15

    $ ifconfig ens33 | grep inet | awk '{print $2}' | cut -d/ -f1 | head -n 1

    ifconfig ens33 | awk '/inet / {print $2}'


    1. Oxyd
      30.08.2021 10:34
      +1

      Вот да! Тоже люблю авку, для парсинга и обработки многоколоночного вывода!


      1. DistortNeo
        30.08.2021 11:17
        +2

        Никаких проблем ровно до тех пор, пока у вас нет пробелов среди значений.


        1. saege5b
          30.08.2021 23:14
          +2

          Скорее: безопасно использовать исключительно литанские буквы и цифры. Всё остальное - хождение по минному полю.


        1. a1111exe
          30.08.2021 23:31

          Никаких проблем ровно до тех пор, пока у вас нет пробелов среди значений.

          Попробуйте

          $ echo "a b c,d e f" | awk 'BEGIN{FS=","};{print $2}'

          Или

          $ echo "a b c,d e f" | awk -F ',' '{print $2}'

          Или Вы о чём-то другом?


          1. DistortNeo
            31.08.2021 00:09
            +1

            Я о ситуации, когда символ-разделитель может встречаться и в значении.
            Например, имена файлов с пробелами.


    1. a1111exe
      30.08.2021 12:39
      +1

      Как вариант:

      $ ifconfig ens33 | grep -Po 'inet \K(\d{1,3}\.){3}\d+'

      Хотя с awk, конечно, элегантнее.


  1. nin-jin
    29.08.2021 18:00
    -3

    JSON не самый лучший выбор для этих целей. Тут я рассказывал про более подходящий формат. Вот пример оттуда:

    > git log
    
    commit
    	message \$mol_style: TS@3.9 compatibility
    	sha \b1a8f07c839604d0d34430a186246f0c1f71e628
    	date \2020-05-15T23:24:32+0300
    	author \nin-jin <jin@example.org>
    commit
    	message \$mol_regexp: concurent parse ability
    	sha \be1abfa50542728dd5c156517ea31f469e7fb4d4
    	date \2020-05-15T23:03:30+0300
    	author \nin-jin <jin@example.org>
    
    > git log | pick date message | table
    
    \2020-05-15T23:24:32+0300	$mol_style: TS@3.9 compatibility
    \2020-05-15T23:03:30+0300	$mol_regexp: concurent parse ability


    1. alexesDev
      30.08.2021 10:03
      +2

      Вам бы курсы личностного роста вести с таким скилом "не забивать" =)


      1. nin-jin
        30.08.2021 11:23

        Я бы может и забил и перешёл на что-то другое, но альтернатив же достойных нет..


    1. Layan
      30.08.2021 14:43

      А чем это принципиально отличается от того же Yaml?


      1. nin-jin
        30.08.2021 15:18

        Там по ссылке статья, всё это разъясняющая.


  1. NeoCode
    29.08.2021 20:07
    +6

    Идея Unix-way хорошая, но как ее соотнести со сложнейшим современным софтом? Да с тем же Офисом, Фотошопом, различными средами разработки, проектирования, конструирования и т.п.?
    Насколько имеет смысл ограничиваться консолью и текстовым форматом (пусть и в JSON)? Не имеет ли смысл пересмотреть концепцию на более глубоком уровне, допустив, что у программ могут быть не только текстовые входы и выходы?


    1. edo1h
      29.08.2021 20:36

      только тот же офис в результате ушёл от бинарных форматов хранения документов.


      1. NeoCode
        29.08.2021 20:50
        +2

        Это несущественно, там xml, который вы руками править точно не будете. Вполне можно было использовать какой-нибудь бинарный аналог. В конечном итоге «текстовость» и «бинарность» — лишь ограничение на множество байт, которые могут быть использованы в файле.
        Дело ведь не в формате, а в том, что всё связывание программ и организация потоков данных осуществляется через командную строку консоли. Когда-то у Microsoft была задумка — COM-объекты, ActiveX, встраивание одних документов и программ в другие… Но в конечном итоге оно пошло куда-то не туда, возможно технология была слишком сложной, или ей чего-то не хватало.


        1. edo1h
          29.08.2021 21:37

          Но в конечном итоге оно пошло куда-то не туда, возможно технология была слишком сложной, или ей чего-то не хватало.

          так про это и речь, de facto простые текстовые протоколы победили.


          1. NeoCode
            29.08.2021 22:17

            Возможно, в технологической гонке упустили несколько промежуточных этапов и скакнули слишком далеко, в результате что-то потеряли и не поняли. Например, кроме «простого текста» могло бы появиться еще несколько «простых» форматов, которые бы стали стандартами де факто и получили бы повсеместное распространение. Или мог бы появиться совсем другой принцип запуска программ, и как следствие — другой способ передачи им аргументов.
            Впрочем, тут можно углубляться очень глубоко. Возможно, дело в текстовой клавиатуре и изначально текстовых интерфейсах пользователя. Или в изначально последовательном командном способе взаимодействия с компьютером. Или еще в чем-то.


        1. matshch
          30.08.2021 00:17
          +2

          там xml, который вы руками править точно не будете

          Как раз-таки правил пару раз этот XML, чтобы зачинить баги форматирования в большом документе. И сделать это было глобально проще, чем писать парсер бинарного формата.


        1. Self_Perfection
          30.08.2021 11:54

          Мне как-то доводилось работать с xlsx документом почти мегабайтного размера, что довольно существенно тормозило, при этом казалось что данных в нём всего ничего. Заглянул внутрь файла, в xml, и оказалось, что в нём объявлены какие-то адские тысячи невидимых объектов.

          Я их удалил sed'ом. Из xml.


  1. Eremite_b
    29.08.2021 21:38
    +3

    А зачем переделывать существующее программное обеспечение, если сам автор, по его словам, уже написал инструмент для унификации вывода? Разве не будет Unix-way, так и оставить, существующее ПО делает свою работу, а программа автора заниматься унификацией вывода?


    1. Loki3000
      06.09.2021 16:28

      Ну он сделал только половину работы. Теперь надо сделать так, чтобы json можно было подать на вход другой программе. То есть надо написать еще и обратный преобразователь:)


  1. GBR-613
    29.08.2021 21:38
    +8

    Всякие "обычные"/"стандартные" утилиты Unix/Linux предназначены в первую очередь для человека, сидящего перед терминалом. Формат JSON всем прекрасен, кроме того, что он не удобен для чтения человеком. Зачем превращать интрумент из того, для чего он предназначен, в то, для чего он не предназначен?

    Если кому нужно что-то очень сложное, он должен не трубопровод строить, а написать программу на Питоне, для которой уже не будет проблемы расшифровать что угодно.


    1. alan008
      30.08.2021 00:13

      JSON вполне читаем человеком, по крайней мере он точно не хуже XML


      1. nin-jin
        30.08.2021 01:49
        +7

        Особенно многострочный текст в нём такой читаемый..


    1. blind_oracle
      30.08.2021 10:52
      +5

      Предлагается опционально выводить в JSON же, с флагом.

      А так можно было бы и YAML, он вполне читабелен и взаимозаменяем с JSON


    1. ElvenSailor
      30.08.2021 11:21

      Если json делать по-человечески , он вполне читаем.

      Если же делать, как например, внутри сэйвов Pathfinder'a, то это лютый трэшак.


    1. fishHook
      30.08.2021 14:33
      +3

      Вы, мне кажется, путаете вопрос структуры данных и их отображения. Если у вас есть просто плоский текст без разметки, то у вас есть единственный способ представить эти данные. Если же это не просто текст, а именно данные структурированные тем или иным способом, то вы можете отобразить эти данные миллионом способов, в том числе в виде плоского текста, если вам так нравится.
      Вот из этого
      {"ip": "127.0.0.1",
      "port": 6000,
      "flags": ["a", "b", "c"]
      }

      фигня вопрос сделать вот это
      127.0.0.1:6000 a,b,c

      а наоборот — нет. Не проблема отобразить данные в удобном для человека виде. Проблема в обратном — чтобы преобразовать данные скриптом, вам надо распарсить текст в некоторое структурированное представление. И вот тут непонятно, почему бы их сразу и не отправлять в удобном для парсинга виде.


  1. le2
    30.08.2021 00:18
    +11

    В комментариях массово не понимают что-такое unix way.
    Программы — мелкие и совершенные (совершенные в прямом смысле слова, если залезть в исходники — часто последнее изменение случилось 20 лет назад).
    Программист/админ не пишет программу «чуть лучше чем было», а строит «трубопровод» — скрипт где мелкие программы передают параметры друг другу. Это позволяет быстро потом разобраться другому программисту. Быстро изменить что-то из этих стандартных кирпичей.
    «Написать на Питоне» часто не выйдет, просто потому что Питон не включен в стандарт Posix. Это невозможно, например, на слабых встраиваемых решениях с 8МБ памяти. А unix way это про универсальное решение для любых машин.
    Также вся система представляет собой «трубопроводы» из стандартных кирпичей — наборы скриптов.
    Всё это позволило системе выжить, стабилизироваться и влезть в телефоны, суперкомпьютеры, сервера и игровые приставки.

    GUI не входит в стандарт POSIX. Речь идет о системном программировании. Здесь гуй не нужен и даже вреден. Исходники ядра Линукса не открывают в IDE, особенно если целевая платформа за тысячи километров с плохой связью.


    1. impwx
      30.08.2021 10:51
      +2

      Программы — мелкие и совершенные
      Это уже давно не так — почитайте статью про разрастание числа параметров в стандартных утилитах. Во многом это происходит именно из-за того, что в качестве формата взаимодействия используется неструктурированный текст.

      Всё это позволило системе выжить, стабилизироваться и влезть в телефоны, суперкомпьютеры, сервера и игровые приставки.
      Выжить экосистеме позволил свободный подход (Bazaar vs Cathedral), но обратная его сторона — усложнение развития и взаимодействия, про которое и идет речь в статье.

      А завоевать рынок позволила, скорее всего, открытость — для многих технологических компаний создавать систему полностью с нуля неподъемно дорого, основываться на решениях конкурентов небезопасно, поэтому единственным рабочим вариантом остается open source.


      1. hrenov_drummer
        31.08.2021 13:23
        +1

        А завоевать рынок позволила, скорее всего, открытость — для многих технологических компаний создавать систему полностью с нуля неподъемно дорого, основываться на решениях конкурентов небезопасно, поэтому единственным рабочим вариантом остается open source.

        Глупости. До появления open source юниксы вполне себе завоевывали рынок, будучи коммерческими. И технологические компании вполне себе строили свои Unix like системы с нуля.


        1. impwx
          31.08.2021 15:30

          Мы с вами про разные эпохи говорим — коммерческие юниксы были актуальны лет 30 назад.


          1. hrenov_drummer
            31.08.2021 16:05
            +2

            Ну если бы юниксы не завоевали популярность и не доказали состоятельность юниксового подхода, никто не стал бы делать опенсорсную версию "типа юникса"

            Кстати, не 30, а гораздо меньше. Солярис был актуален для больших машин в энтерпрайзе еще лет 10 назад и линукс был довольно слабой альтернативой.


    1. tyomitch
      30.08.2021 14:11
      -1

      «Написать на Питоне» часто не выйдет, просто потому что Питон не включен в стандарт Posix. Это невозможно, например, на слабых встраиваемых решениях с 8МБ памяти.

      MicroPython работает даже с 16KB памяти.


      1. Oxyd
        30.09.2021 23:47

        MicroPython отличается от полноценного пайтона, примерно так же, как JavaME от полноценного рантайма. Вы-б ещё BusyBox с полноценными core/linux/find-utils сравнили.


        1. tyomitch
          30.09.2021 23:59

          В топике речь про продвинутые шелл-скрипты, а не про Django и Pandas.
          Для продвинутых шелл-скриптов возможностей MicroPython хватает с запасом.


    1. semmaxim
      28.09.2021 12:06

      Подождите, но любая программа тоже "трубопровод" из совершенных кирпичиков стандартных лексем "if", "switch" и базовых элементов стандартной библиотеки типа "Math.Cos". И за последние 20 лет наработки в области читабельности сделали огромнейший шаг вперёд. А вот в этом unix-way сложность понимая растёт буквально экспоненциально с увеличением размера скрипта.


      1. le2
        28.09.2021 12:58
        +1

        у разработчиков UNIX был нищебродский компьютер PDP-11. Под ось, если не ошибаюсь они выделили 8k, а для программ 4k — 18битных слов. То есть 9 кБ. Вот откуда вся философия в первую очередь.
        То есть ты можешь дергать системные функции как printf либо твоя программа должна умещаться в эти 9 кБ. Память была на тороидальных трансформаторах. Дисплея также не было, все через телетайп.
        Когда придумали скрипты — вышло отлично — каждый вызываемый кирпич после себя освобождает память полностью.
        Вторая проблема — нет интернета, нет стековерфлоу. Документации также нет. Вся документация это man и на крайний случай исходники. В сложных монструозных проектах тяжело разбираться.

        Гугл пишет свои системы сборки на питоне или java, это хорошо, я этим с удовольствием пользуюсь. Но представьте что вам нужно починить компьютер в закрытом заведении. Вы даже не знаете что за версия там. Нет интернета. В POSIX-системах это не проблема. По стандарту там есть gcc, bash, vi и man — вся документация. Этого достаточно. Интернет не нужен чтобы искать документацию на конкретные версии, все уже там, инструменты также там. Программы короткие и простые. Совершенные) Разобраться также будет не сложно.

        В вашем же случае, в случае нестандарта, окажется что исходников нет, а если нет, то нет компилятора. Если компилятор есть, то нужно отдельно искать документацию и так далее.
        Любой стандарт не только зло, но и добро. А POSIX это стандарт. Конечно, сейчас уже мало кто кладет в систему Фортран, который требуется по-стандарту, но представьте что сейчас в 2021 году не представит труда починить какой-то unix-сервер из 1990 года, когда вендор может уже разорился.


        1. semmaxim
          28.09.2021 13:48
          -1

          Так о том и речь. Что переносить философию Unix в 21 век совершенно бессмысленно. Интерпретатор питона работает даже под 98 виндой. Поставить его просто (а с практически любым пакетным менеджером - очень просто) или вообще можно принести в виде portable. И он уже давно поставляется в базе практически любого дистрибутива. То же самое касается и java.


          1. le2
            28.09.2021 14:05
            +2

            Posix это стандарт. Величайшее достижение человечества. Одну и ту же программу можно пересобрать под игровую приставку, телефон, суперкомпьютер и тучи эмбеддед железок. С Питоном так не выйдет, потому что в стандарт не входит.
            Не, ну большинство языков программирования внезапно транслируются в Си-код, а этот код потом собирает Си-компилятор. Который также детище unix.
            Питоновские библиотеки также часто написаны на Си и верхний уровень только дергает их. Сам питон тоже конечно можно пересобрать.
            Мир не ограничен десктопом. Большинство выпускаемого железа это вообще не десктоп, а всякие роутеры, автомобильные компьютеры и прочее прочее. Там Питон это не то что идет в продакшн, а только для быстрого прототипирования.


            1. DistortNeo
              28.09.2021 15:18
              +1

              С Питоном так не выйдет, потому что в стандарт не входит.

              Почему? Интерпретатор Python — это же обычное приложение, которое будет работать на любой POSIX-совместимой ОС. В свою очередь, Python также предоставляет некоторый стандартный функционал.


              Не, ну большинство языков программирования внезапно транслируются в Си-код, а этот код потом собирает Си-компилятор.

              Мне кажется, вы немного отстали от жизни. Для компилируемых языков сейчас в тренде LLVM-бэкэнд.


              1. Oxyd
                01.10.2021 00:10

                Ну поставьте питон на мой, не сильно свежий, асусовский роутер под OpenWRT. Я вам скажу сразу. У вас не получится. Там просто не хватает места на накопителе, под такие шалости. Поэтому и ансибль приходится применять к нему в виде модуля shell.


            1. Oxyd
              01.10.2021 00:05

              Ну на linux смартфонах Nokia N9 и особенно на Nokia N900, питон очень активно использовался как для написания софта, так и для всякой околосистемщины Так что не всё так однозначно © Опять-же, если вспомнить пакетный менеджер yum...


          1. Oxyd
            30.09.2021 23:58

            Ну раз заговорили про 98-ю винду... Не далее как сегодня, у человека у которого в хозяйстве энное количество AIX-ов, на IBM Power... Вообщем Python там ставится отдельно и он далеко не 3.x ветки... И лежит по нестандартному пути. Поэтому ansible берёт и обламывается. Пришлось костылить, через POSIX утилиту, кстати, ansible_python_interpreter=/usr/bin/env python в инвентори. И оно работает! Но опять-же, тот-же sh есть чуть менее чем везде.


  1. chernish2
    30.08.2021 00:45
    +1

    Как Вы пишите, JSON появился в 2013 году, однако я с ним работал уже в 2010.


    1. Devoter
      30.08.2021 18:04
      +2

      Работал с ним в 2008, а история гласит, что появился он и вовсе в 2001. А вот стандарт, да, был принят в 2013. Но это же рувдс, у них от автора к автору качествео вычитки скачет.


  1. pansa
    30.08.2021 01:45
    +2

    Просто оставлю это здесь https://habr.com/ru/company/mailru/blog/314014/


  1. PaulZi
    30.08.2021 01:50
    +2

    У json есть фатальный недостаток - отсутствия поддержки бинарных данных.


    1. uranik
      30.08.2021 02:04
      +2

      uuencode, uudecode в помощь, накладные для процессора не ощущаются, ну чуть больше памяти сожрет, не критично.


  1. xotkot
    30.08.2021 05:18
    +1

    $ lsblk --help | grep json

    -J, --json использовать для вывода формат JSON

    $ lsblk --version

    lsblk из util-linux 2.37.2


  1. fardok
    30.08.2021 05:18
    +2

    Отлично. Теперь я могу сделать jdemon который через рест апи будет выдавать json от всех этих штук


  1. st1373
    30.08.2021 15:29
    -1

    The ip command is the future of network config commands. ifconfig has been officially deprecated for the ip suite, so while many of us are still using the old ways, it is time to put those habits to rest and move on with the world.

    а далее что human is depricated?


  1. grayich
    30.08.2021 17:06

    А вот ip route, не выводящий JSON, даже с флагом -j:

    > ip -V
    ip utility, iproute2-5.13.0
    
    > ip -j route
    [{"dst":"default","gateway":"192.168.5.1","dev":"enp37s0","protocol":"dhcp","metric":100,"flags":[]},{"dst":"192.168.5.0/24","dev":"enp37s0","protocol":"kernel","scope":"link","prefsrc":"192.168.5.102","metric":100,"flags":[]}]
    


  1. groser
    31.08.2021 12:09
    -1

    Выглядит так, как будто автор не знает о существовании powershell для Linux. В нём и JSON гонять можно и конвееры человеческие писать. Вот это, действительно, решение 21-го века!


    1. DistortNeo
      31.08.2021 18:17

      А ничего, что PowerShell под Linux имеет урезанный функционал и даже не входит в официальные репозитории?


  1. Kirikekeks
    31.08.2021 22:19
    +1

    Selinux, auditctl предельно некомфортные для работы программы. Думаю из за бинарности, нечитаемости. Они не настолько сложные, что бы быть настолько отвратительными, в прямом понимании. По любви с ними никто не имеет дела.