33.5. "Цветные" сценарии


33.5. "Цветные" сценарии

Для установки атрибутов отображения информации на экране, таких как: жирный текст, цвет символов, цвет фона и т.п., с давних пор используются ANSI [62] escape-последовательности. Эти последовательности широко используются в пакетных файлах DOS, эти же последовательности используются и в сценариях Bash.

Пример 33-9. "Цветная" адресная книга

  1. #!/bin/bash
  2. # ex30a.sh: Версия сценария ex30.sh, с добавлением цвета .
  3. #           Грубый пример базы данных
  4. clear                                   # Очистка экрана
  5. echo -n "          "
  6. echo -e '\E[37;44m'"\033[1mСписок\033[0m"
  7.                                         # Белый текст на синем фоне
  8. echo; echo
  9. echo -e "\033[1mВыберите интересующую Вас персону:\033[0m"
  10.                                         # Жирный шрифт
  11. tput sgr0
  12. echo "(Введите только первую букву имени.)"
  13. echo
  14. echo -en '\E[47;34m'"\033[1mE\033[0m"   # Синий
  15. tput sgr0                               # сброс цвета
  16. echo "vans, Roland"                     # "[E]vans, Roland"
  17. echo -en '\E[47;35m'"\033[1mJ\033[0m"   # Пурпурный
  18. tput sgr0
  19. echo "ones, Mildred"
  20. echo -en '\E[47;32m'"\033[1mS\033[0m"   # Зеленый
  21. tput sgr0
  22. echo "mith, Julie"
  23. echo -en '\E[47;31m'"\033[1mZ\033[0m"   # Красный
  24. tput sgr0
  25. echo "ane, Morris"
  26. echo
  27. read person
  28. case "$person" in
  29. # Обратите внимание: переменная взята в кавычки.
  30.   "E" | "e" )
  31.   # Пользователь может ввести как заглавную, так и строчную букву.
  32.   echo
  33.   echo "Roland Evans"
  34.   echo "4321 Floppy Dr."
  35.   echo "Hardscrabble, CO 80753"
  36.   echo "(303) 734-9874"
  37.   echo "(303) 734-9892 fax"
  38.   echo "revans@zzy.net"
  39.   echo "Старый друг и партнер по бизнесу"
  40.   ;;
  41.   "J" | "j" )
  42.   echo
  43.   echo "Mildred Jones"
  44.   echo "249 E. 7th St., Apt. 19"
  45.   echo "New York, NY 10009"
  46.   echo "(212) 533-2814"
  47.   echo "(212) 533-9972 fax"
  48.   echo "milliej@loisaida.com"
  49.   echo "Подружка"
  50.   echo "День рождения: 11 февраля"
  51.   ;;
  52. # Информация о Smith и Zane будет добавлена позднее.
  53.           * )
  54.    # Выбор по-умолчанию.
  55.    # "Пустой" ввод тоже обрабатывается здесь.
  56.    echo
  57.    echo "Нет данных."
  58.   ;;
  59. esac
  60. tput sgr0                               # Сброс цвета
  61. echo
  62. exit 0

Самая простая и, на мой взгляд, самая полезная escape-последовательность — это "жирный текст", \033[1m ... \033[0m. Здесь, комбинация \033 представляет escape-символ, кобинация "[1" — включает вывод жирным текстом, а "[0" — выключает. Символ "m" — завершает каждую из escape-последовательностей.

  1. bash$ echo -e "\033[1mЭто жирный текст.\033[0m"
  2.        


Простая escape-последовательность, которая управляет атрибутом подчеркивания (в rxvt и aterm).

  1. bash$ echo -e "\033[4mЭто подчеркнутый текст.\033[0m"
  2.        


Note

Ключ -e, в команде echo, разрешает интерпретацию escape-последовательностей.

Другие escape-последовательности, изменяющие атрибуты цвета:

  1. bash$ echo -e '\E[34;47mЭтот текст выводится синим цветом.'; tput sgr0
  2. bash$ echo -e '\E[33;44m'"желтый текст на синем фоне"; tput sgr0
  3.        
Команда tput sgr0 возвращает настройки терминала в первоначальное состояние.

Числовые значения цвета, приведенные ниже, справедливы для rxvt. Для других эмуляторов они могут несколько отличаться.

Таблица 33-1. Числовые значения цвета в escape-последовательностях

Цвет Текст Фон
черный 30 40
красный 31 41
зеленый 32 42
желтый 33 43
синий 34 44
пурпурный 35 45
зеленовато-голубой 36 46
белый 37 47

Пример 33-10. Вывод цветного текста

  1. #!/bin/bash
  2. # color-echo.sh: Вывод цветных сообщений.
  3. black='\E[30;47m'
  4. red='\E[31;47m'
  5. green='\E[32;47m'
  6. yellow='\E[33;47m'
  7. blue='\E[34;47m'
  8. magenta='\E[35;47m'
  9. cyan='\E[36;47m'
  10. white='\E[37;47m'
  11. cecho ()                     # Color-echo.
  12.                              # Аргумент $1 = текст сообщения
  13.                              # Аргумент $2 = цвет
  14. {
  15. local default_msg="Нет сообщений."
  16.                              # Не обязательно должна быть локальной.
  17. message=${1:-$default_msg}   # Текст сообщения по-умолчанию.
  18. color=${2:-$black}           # Цвет по-умолчанию черный.
  19.   echo -e "$color"
  20.   echo "$message"
  21.   tput sgr0                  # Восстановление первоначальных настроек терминала.
  22.   return
  23. }
  24. # Попробум что-нибудь вывести.
  25. # ----------------------------------------------------
  26. cecho "Синий текст..." $blue
  27. cecho "Пурпурный текст." $magenta
  28. cecho "Позеленевший от зависти." $green
  29. cecho "Похоже на красный?" $red
  30. cecho "Циан, более известный как цвет морской волны." $cyan
  31. cecho "Цвет не задан (по-умолчанию черный)."
  32.        # Аргумент $color отсутствует.
  33. cecho "\"Пустой\" цвет (по-умолчанию черный)." ""
  34.        # Передан "пустой" аргумент цвета.
  35. cecho
  36.        # Ни сообщение ни цвет не переданы.
  37. cecho "" ""
  38.        # Функции переданы "пустые" аргументы $message и $color.
  39. # ----------------------------------------------------
  40. echo
  41. exit 0
  42. # Упражнения:
  43. # ---------
  44. # 1) Добавьте в функцию 'cecho ()' возможность вывода "жирного текста".
  45. # 2) Добавьте возможность управления цветом фона.
Caution

Однако, как обычно, в бочке меда есть ложка дегтя. Escape-последовательности ANSI совершенно не переносимы. Вывод в одном эмуляторе терминала (или в консоли) может разительно отличаться от вывода в другом эмуляторе. "Расцвеченные" сценарии, дающие изумительно красивый вывод текста на одном терминале, могут давать совершенно нечитаемый текст на другом. Это ставит под сомнение практическую ценность "расцвечивания" вывода в сценариях, низводя ее до уровня никчемной "игрушки".

Moshe Jacobson разработал утилиту color (http://runslinux.net/projects/color), которая значительно упрощает работу с ANSI escape-последовательностями, заменяя, только что обсуждавшиеся, неуклюжие конструкции, логичным и понятным синтаксисом.


[62]    ANSI — аббревиатура от American National Standards Institute.