Метка «pipe»

Чем больше я пишу однострочники в шелле, тем больше я прихожу к двум важным идеям:

  1. Это очень мощное средство для «непосредственного программирования», то есть указания компьютеру, что делать.
  2. Большая часть однострочника посвящена grep/awk/cut/tr, которые каким-то образом выковыривают и приводят в человеческий вид вывод предыдущих утилит.

При том, что модель pipe'ов восхитительна, совершенно грязные хаки по отлову нужных полей в выводе во втором пункте («а вот тут мы можем выделить нужное нам по характерной запятой с помощью awk -F, '{print $2}'...) делают процедуру спорной по удовольствию, и уж точно нечитаемой.

Ещё одна серьёзная проблема: при том, что шелл даёт довольно много идиом из функционального программирования, в нём нет идиомы фильтрации списка по результату выполнения внешней программы. То есть „грепнуть“ список мы можем. А вот оставить в списке только те элементы, для которых какая-то программа вернула „успех“ — нет.

При этом есть враждебная и не очень хорошо написанная среда — powershell (винды). В которых взяли хорошую идею (пайпы передают не текст, а объекты), но испортили её двумя вещами:

  1. Неэргономичной консолью виндов (Shift-PgUp где, а? говорят, Ctrl-PdUp в новых версиях)
  2. предложением пойти и выучить .net для того, чтобы нормально с методами работать.
  3. Отсутствием под большинство операционных систем

Хочется иметь объекты в пайпе в тёплом ламповом линуксовом шелле. С hand-candy (мало печатать), eye-candy (приятно смотреть) и общей эргономичностью процесса использования. Ещё хочется иметь возможность сочетать „новый подход“ со старым, то есть обычным текстовым pipe'ом.

Идея

Надо написать набор инструментов, которые позволят в pipe-style оперировать с структурированными данными. Очевидным выбором является XML JSON.
Нам нужно:

  1. Утилиты, которые примут типовые форматы на вход и сконвертируют их в json.
  2. Утилиты, которые позволят в pipe'е манипулировать с json'ом.
  3. Утилиты, которые приведут json в „обычный“ формат.

В этом случае человек не будет видеть json на экране, но будет иметь возможность работать с ним.

Для затравки

(для понимания я буду писать длинные имена утилит, в реальной жизни это будут короткие сокращения, то есть не json-get-object, а что-то типа jgo или jg)

Выводит только файлы, для которых file сумел определить тип:
ls -la | ls2json | json-filter 'filename' --exec 'file {} >/dev/null' | json-print

Выкачивает с некоторого сайта токен для авторизации, выковыривает его из json'а и выставляет в переменные среды окружения, после чего скачивает список и отфильтровав по регэкспу поле „автор“ выкачивает все url'ы:
curl mysite/api.json | env `json-get-to-env X-AUTH-TOKEN`;curl -H X-AUTH-TOKEN $X-AUTH-TOKEN mysite/api/list.json | json-filter --field 'author' --rmatch 'R.{1,2}dald*' | json-get --field 'url' | xargs wget

Парсит вывод find -ls, сортирует по полю size, вырезает из массива элементы с 10 по 20, выводит их в csv.
find . -ls | ls2josn | json-sort --field 'size' | json-slice [10:20] | json2csv

Читать полностью »

в 9:22, , рубрики: bash, linux, pipe, метки: , ,

Pipe — что это?

Pipe (конвеер) – это однонаправленный канал межпроцессного взаимодействия. Термин был придуман Дугласом Макилроем для командной оболочки Unix и назван по аналогии с трубопроводом. Конвейеры чаще всего используются в shell-скриптах для связи нескольких команд путем перенаправления вывода одной команды (stdout) на вход (stdin) последующей, используя символ конвеера ‘|’:

cmd1 | cmd2 | .... | cmdN

Например:

$ grep -i “error” ./log | wc -l
43

grep выполняет регистронезависимый поиск строки “error” в файле log, но результат поиска не выводится на экран, а перенаправляется на вход (stdin) команды wc, которая в свою очередь выполняет подсчет количества строк.

Логика

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

Размер буфера начиная с ядра версии 2.6.11 составляет 65536 байт (64Кб) и равен странице памяти в более старых ядрах. При попытке чтения из пустого буфера процесс чтения блокируется до появления данных. Аналогично при попытке записи в заполненный буфер процесс записи будет заблокирован до освобождения необходимого места.
Важно, что несмотря на то, что конвейер оперирует файловыми дескрипторами потоков ввода/вывода, все операции выполняются в памяти, без нагрузки на диск.
Вся информация, приведенная ниже, касается оболочки bash-4.2 и ядра 3.10.10.

Простой дебаг

Утилита strace позволяет отследить системные вызовы в процессе выполнения программы:

$ strace -f bash -c ‘/bin/echo foo | grep bar’
....
getpid() = 13726                   <– PID основного процесса
...
pipe([3,  4])                       <– системный вызов для создания конвеера
....
clone(....) = 13727                <– подпроцесс для первой команды конвеера (echo)
...
[pid 13727] execve("/bin/echo",  ["/bin/echo",  "foo"],  [/* 61 vars */] 
.....
[pid 13726] clone(....) = 13728    <– подпроцесс для второй команды (grep) создается так же основным процессом
...
[pid 13728] stat("/home/aikikode/bin/grep",   
...

Видно, что для создания конвеера используется системный вызов pipe(), а также, что оба процесса выполняются параллельно в разных потоках.
Читать полностью »

Наверное, каждый, кому когда-нибудь приходилось следить одновременно за большим количеством окошек с логами, подумывал о переносе некоторых из них на экран планшета или телефона.
А, находясь далеко от компьютера, следить за выхлопом недавно запущенного большого и страшного сервиса?
Конечно, можно поставить ssh клиент на телефон, но это не особо удобно.
Поэтому я решил сделать мини-сервис упрощающий «удалённый» просмотр логов.

Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js