Функция Bash для создания цветных выход


Я люблю пользователя цветной вывод в моем интерактивных скриптов.

Я использую Ubuntu и Баш уже давно, но не делали много скриптах bash.

Я был бы признателен за обзор этой функции для генерации цветного вывода.

#!/usr/bin/env bash
#
# Function to generate colored output.
#
# The output is specified using a format string and arguments, similar to printf.
#
# All special format specifiers are enclosed in parenthesis.
# Colors start with either "f" for foreground or "b" for background with the
# remainder of the specifier being the color name, starting with a capital
# letter (e.g., fRed or bCyan).
#
# There are a few other specifiers in addition to the colors:
# - %s%         Placeholder; consumes the next argument from the command line
# - %u%         Underline
# - %r$         Reverse video
# - %default%   Default foreground and background color
# - %reset%     Reset all attributes
#
# Example:
#   echoc '%fRed%The value "%r%%s%%fRed%" is not valid for the --trace option' extra
# Result:
#   The value "extra" is not valid for the --trace option
#   with everything except the word extra being red on the default background
#   color and the word extra being reverse-video.
#
unset -f echoc
function echoc()
{
  local       char
  local       code
  local       fmt="${1}"
  local       fmtLen=${#fmt}
  local       i=0
  local       output=''
  local       str=''
  local       tagActive=0

  shift       # Remove the format string.

  #
  # The ANSI color and format codes.
  # Keys that start with "f" are foreground colors.
  # Keys that start with "b" are background colors.
  # Other keys are eight resets or other formatting codes.
  # The "r" and "u" are reverse and underscore, respectively.
  #
  declare -A colors
  colors=(['fBlack']='30' ['fBlue']='34' ['fBrown']='33' ['fCyan']='36')
  colors+=(['fDarkgray']='1;30' ['fDefault']='39' ['fGreen']='32' ['fLavender']='1;34')
  colors+=(['fLightblue']='1;36' ['fLightgray']='37' ['fLightgreen']='1;32')
  colors+=(['fLightpurple']='1;35' ['fMagenta']='35' ['fPink']='1;31' ['fPurple']='35')
  colors+=(['fRed']='31' ['fWhite']='1;37' ['fYellow']='1;33')
  colors+=(['bBlack']='40' ['bBlue']='44' ['bBrown']='43' ['bCyan']='46' ['bDefault']='49')
  colors+=(['bGreen']='42' ['bMagenta']='45' ['bPurple']='45' ['bRed']='41')
  colors+=(['default']='39;49' ['reset']='0')
  colors+=(['r']='7' ['u']='4')


  #
  # Parse the format string, building the output string as we go.
  #
  while [ $i -lt $fmtLen ]
  do
    char="${fmt:i:1}"
    case $char in
      %)
        if [ 0 -eq $tagActive ]
        then
          if [ -n "${str}" ]
          then
            output="${output}${str}"
            str=''
          fi
          tagActive=1
        else # tagActive is true.
          if [ -z "${str}" ]
          then
            output="${output}%" # %% inserts a percent sign.
          else
            if [ 's' == "${str}" ]
            then
              output="${output}${1}\033[0m"
              shift
            else
              code="${colors[$str]}"
              if [ -z "${code}" ]
              then
                echo -e "\033[31mInvalid color name \"${str}\"\033[0m"
              else
                output="${output}\033[${code}m"
              fi
            fi
            str=''
          fi
          tagActive=0
        fi
        ;;

      *)
        str="${str}${char}"
        ;;
    esac
    ((i++))
  done
  if [ -n "${str}" ]
  then
    output="${output}${str}"
  fi
  output="${output}\033[0m"
  echo -e "${output}"

}
export -f echoc


128
4
задан 3 февраля 2018 в 07:02 Источник Поделиться
Комментарии
2 ответа

Три вещи сразу же поражают меня:


  1. Вы лечите цвета переднего плана и фона одинаково, и отдавая предпочтение инверсном и подчеркнуть(?). Почему красный текст %Фред%, тогда как обратный видео %Р%? Не вы скорее всего, использовать красный,желтый,зеленый переднем плане, чем инверсном? Разве вы не более склонны использовать цвета, чем цвета фона?

    Я думаю, вы должны дать некоторую мысль к "Huffmanization" из вашего названия цветов. Может быть, вам нужно %r% %g% %y% как ярлыки на переднем плане красный, зеленый и желтый. (Или, может быть, не. Это зависит от того, что в вашем случае будет. Если вы пишете изгоев, как в bash, может быть, у вас другой цвет словарный запас...)

    Я бы предположил, что изображения цветов просто названия цветов, в то время как фоновые цвета есть bg префикс: %cyan% против %bgCyan% например. Это делает цвета фона дороже, чем в настоящее время (1 лишний символ), но и делает цвета менее дорогие, и я подозреваю, что они будут более распространены.


  2. Далее, я думаю, вы делаете слишком много работы внутри вашего цикла. Вы на самом деле обработка формат строки посимвольно! Учитывая, что начало и окончание разделитель разделитель одинаковы - % - вы могли бы использовать МФС, чтобы разделить строку в массив и обрабатывать сегментов массива. Дана строка типа "раньше % во % После", или даже "%на%", вы знаете, что заместители членов массива будут теги: четных позициях текста, нечетные тэг показателей.

    Увидеть этот ответ на так Для как разделить строку.

    Это позволит изменить ваш цикл от обработки символов в переработку "струны", и следует ускорить свои функции.


  3. Наконец, есть много "магических строк" в код. Как магия чисел, вы должны заменить их на постоянные (переменные) и ссылаться на них только один раз. В частности, я думаю ${pfx} ("\033[") и может быть ${reset} ("${файл}0м").

1
ответ дан 4 февраля 2018 в 09:02 Источник Поделиться

Escape-последовательности, начиная с ESC последовательность (\033) для типа терминала или терминала-эмулятора, который вы используете. Вы могли бы сделать код намного более портативные терминалы с различных управляющих кодов или без цветные/смелые поддержки, если вы вместо того, чтобы использовать tput программа для создания правильного выхода, чтобы соответствовать $TERM это в использовании.

0
ответ дан 5 февраля 2018 в 10:02 Источник Поделиться