понедельник, 11 апреля 2011 г.

Интерфейс консольных утилит UNIX-like системз

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


    Итак, выведу некоторые правила и критерии, которых буду придерживаться в своих дальнейших разработках:

Обязательные:
  1. Любая консольная тулза выполняет строго одно действие и делает это хорошо, понятно и непротиворечиво;
  2. Сообщения об ошибках пишутся исключительно в STDERR;
  3. Тулза должна понимать аргументы: "-h, --help, -?, -v, --version";
Благодаря чтению книги "Программное обеспечение UNIX" Брайна Кернигана мне стало понятно, что в большинстве случаев разрабатываю программы-фильтры. Эти программы предназначены для обработки некоторых входных данных и подачи на выход. Очень часто подобного рода программ можно встретить в соединениях с чем-либо через "пайп", банальный пример:
# dmesg | grep CPU 
    Тут тулза grep как раз выступает в роли фильтра, т.к. берет на входе данные от dmesg -> обрабатывает -> выдает на выход, точнее STDOUT, который по дефолту связан с терминалом.

    К тулзам-фильтрам можно выставить обязательные для выполнения требования, по мимо тех что указаны в верху:
  1. Если не заданы входные данные через аргументы командной строки, то их надо брать из STDIN;
  2. В случае если ну указаны сведения куда выводить результат, то его нужно выводить в STDOUT;
    Реализуя работу с STDIN, STDOUT, STDERR в своей тулзе вы тем самым дадите возможность пользователю включить свою тулзу в код скрипта. Ведь до вашей тулзы может сколь угодно большое количество других программ, которые  в свою очередь могут брать данные из баз данных, сетевых ресурсов, файлов, устройств и т.д. и т.п. Также после вашей тулзы возможно неменее большое чем на входе количество программ, которые также как и на входе могут отдавать данные в сеть, базы данных, файлы, устройства и т.д. и т.п.

   Взглянем некоторых поток команд связанных посредством механизма "пайп", который поддерживают, чуть ли не все UNIX командные интерпретаторы:
% trojan_gen --compiller_type=MSVC --compiller_version=v90 | malware_cryptor --complexity_level=2 | tee sample.bin | send2client --list=clients_emails.lst
    Пример конечно надуманный и в реальности врядли встретится по причине громоздкости и неуклюжести, но тем не менее пример показывает что "malware_cryptor" выступает в роли тулзы-фильтра и что его можно удобно использовать реализовав работу с STDIN\STDOUT соглассно  критериям для тулзов-фильтров указанных выше.


    Вы только вдумайтесь, какой сложный процесс обработки можно создать и при этом не особо парясь! А ведь всего достаточно знать принцип UNIX-утилит:
Тулза должна делать ровно одно дело и ничего более, при этом делать его хорошо! 
P.S.:
Советую почитать на хабре статью под названием " Команда dd и все, что с ней связано " . Она дает понимание "UNIX way". 

Комментариев нет: