10 августа 2012

Pipeline, shell и функции

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

Так вот это маленькая подсказка как научить функцию читать вывод другой программы.

Для примера попробуем раскрасить вывод абстрактного лога:

08-08-2012 12:00 DBG LOVE ALL HUMANS!
08-08-2012 12:01 DBG LOVE ALL HUMANS!
08-08-2012 12:02 DBG LOVE ALL HUMANS!
08-08-2012 12:03 DBG LOVE ALL HUMANS!
08-08-2012 12:04 DBG LOVE ALL HUMANS!
08-08-2012 12:05 ERR KILL ALL HUMANS!
08-08-2012 12:06 INF OK!

Что бы вывести лог нужно воспользоваться командой cat. Тут проблем нет. Что бы раскрасить вывод cat можно заменить DBG, ERR и INF с помощью sed на такой же текст, но обрамленный спец символами цвета \033[31m для красного, \033[32m для зеленого и \033[33m для желтого. Что бы сбросить цвет в нормальный после подсвеченного фрагмента, нужно использовать код \033[0m.

Что бы не ходить вокруг до около, вот скрипт:

#!/bin/sh

hi() {
  local red=$(echo -e '\033[31m')
  local green=$(echo -e '\033[32m')
  local yellow=$(echo -e '\033[33m')
  local reset=$(echo -e '\033[0m')
  while read data
  do
    echo $data | sed -e "s/\(DBG\)\(.*$\)/$green\1$reset\2/" \
               | sed -e "s/\(ERR\)\(.*$\)/$red\1$reset\2/" \
               | sed -e "s/\(INF\)\(.*$\)/$yellow\1$reset\2/"
  done
}

cat example.log | hi

Как видно, что бы функция hi смогла все подсветить, нужно воспользоваться конструкцией while read data которая и будет читать в переменную $data вывод команды cat.

Вот собственно и все.