Раскрашивание вывода консольного скрипта Ruby

Mar 23
2007 18:28 (Программирование, Ruby on Rails) · English (13,291 views)

Довольно часто мне приходится (или из-за врожденной лени для оптимизации каких-то рутинных вещей) писать консольные скрипты. Многие из них выводят какую-то информацию, отображают статус процесса или выводят результаты своей работы. Как бы то ни было, читать весь вывод скрипта бывает довольно утомительным занятием, и хочется каким-то образом подсветить наиболее важные моменты вывода: ошибки красным, успех ключевых шагов зеленым и т.д. И тут на помощь приходят управляющие коды ANSI, поддерживаемые многими терминалами, включая VT100 (кстати, консоль Windows семейства NT не поддерживает, но об этом ниже).

Для начала, рассмотрим, что же представляет из себя ANSI-последовательность. Она начинается с символа ESC (ASCII-код 27) с последующим символом открывающей квадратной скобки [. Далее следует одно или несколько чисел, разделенных точкой с запятой ;, и завершается буквой.

Я не буду описывать все возможные коды, желающие могут найти их в Wikipedia. Для изменения цвета и фона используется последовательность, завершающаяся символом m, и в общем виде выглядит так: ESC[31m, где 31 - установка цвета текста в красный. Вот таблица кодов, поддерживаемых большинством терминалов:

Код Эффект
0 Сбросить все атрибуты
1 Установить повышенную яркость
4 Включить подчеркивание
5 Включить мигание
7 Поменять местами цвет фона и цвет текста
8 Скрыть текст (цвет у текста установливается такой же, как и у фона)
30 Черный текст
31 Красный текст
32 Зеленый текст
33 Желтый текст
34 Синий текст
35 Пурпурный текст
36 Голубой текст
37 Белый текст
39 Цвет текста по умолчанию
40 Черный фон
41 Красный фон
42 Зеленый фон
43 Желтый фон
44 Синий фон
45 Розовый фон
46 Голубой фон
47 Белый фон
49 Цвет фона по умолчанию

Как видно из таблицы, цвет фона и текста устанавливается отдельными кодами, которые можно комбинировать в одну последовательность (например, ESC[1;33;44m - желтый текст на синем фоне, повышенная яркость).

Внимание: Не забудьте сбросить атрибуты перед выходом из скрипта, иначе весь последующий текст будет отображаться с Вашими атрибутами.

Хватит теории, рассмотрим пример:

# Actual work
puts "Importing categories [ \e[32mDONE\e[0m ]"
# Actual work
puts "Importing tags       [\e[31mFAILED\e[0m]"

В результате работы вы увидите что-то вроде:

VT100 Example 1

Всю жизнь использовал коды именно так, как показано в примере, но недавно, когда ковырял исходники RSpec и наткнулся на простенькие хелперы:

def colorize(text, color_code)
  "#{color_code}#{text}\e[0m"
end

def red(text); colorize(text, "\e[31m"); end
def green(text); colorize(text, "\e[32m"); end

# Actual work
puts 'Importing categories [ ' + green('DONE') + ' ]'
# Actual work
puts 'Importing tags       [' + red('FAILED') + ']'

Идея хорошая, так теперь и пользую. Чего и Вам желаю :-)

Теперь о грустном. Windows XP (и, насколько я помню, Windows 2000 тоже) не поддерживают ANSI-последовательности. Кто любит поизвращаться, вперед читать статью Command Interpreter Ansi Support, остальные могут остаться здесь и взглянуть, как проблема решается средствами Ruby.

Для начала нужно установить win32console:

gem install win32console

Теперь добавьте в начало вашего скрипта следующие строки (взято, опять-таки, из RSpec):

begin
  require 'Win32/Console/ANSI' if PLATFORM =~ /win32/
rescue LoadError
  raise 'You must gem install win32console to use color on Windows'
end

Вывод скрипта будет раскрашенным как в Windows, так и в Unix-системах.

Ну и напоследок приведу полную таблицу разных кодов, которые вы можете использовать в своих скриптах:

VT100 Terminal

Получена с помощью следующего скрипта:

#!/usr/bin/ruby

[0, 1, 4, 5, 7].each do |attr|
  puts '----------------------------------------------------------------'
  puts "ESC[#{attr};Foreground;Background"
  30.upto(37) do |fg|
    40.upto(47) do |bg|
      print "\033[#{attr};#{fg};#{bg}m #{fg};#{bg}  "
    end
  puts "\033[0m"
  end
end

9 отзывов на 'Раскрашивание вывода консольного скрипта Ruby'

Подписаться на комментарии по RSS или TrackBack на 'Раскрашивание вывода консольного скрипта Ruby'.

1
shaliko
сказал 24.03.2007 в 15.24

Большое спасибо за статью!

Непременно воспользуюсь всем выше перечисленным..

2
Shatyorkin
сказал 27.03.2007 в 11.58

Классная штука - я это для тестов приспособил.

3
сказал 12.07.2007 в 0.13

Thanks for the code, it helped a lot for a console app that I am working on.

4
сказал 25.07.2007 в 0.17

This is a great article. If you continue to write interesting things like this I will have to subscribe to your feed!

5
сказал 12.10.2007 в 9.57

спасибо за статью. я как–бы думал, што у руби может быть свой стиль колоризации, но оказывается это те же саммые анси .)

6
Artem Vasiliev
сказал 27.11.2007 в 18.54

Круто, спасибо!

Прикрутил это у себя и к серверной консоли, и к autotest..

Правда, не без помощи такой-то матери - простое добавление в environment.rb для autotest не достаточно, пришлось продублировать в .autotest

7
pmil
сказал 27.02.2008 в 23.31

I have similar problem but I wanted to see Rails log colors in win console.
A little addition.
1. create file console.rb

require 'rubygems'
require 'win32console'
include Win32::Console::ANSI
include Term::ANSIColor

puts bold
8
сказал 06.05.2008 в 7.40

[...] Colorizing console Ruby-script output | Dmytro Shteflyuk’s Home Colorizing console Ruby-script output (tags: Ruby ansi console code) [...]

9
сказал 15.07.2008 в 5.36

Я так делаю обычно:

class String

    def red; colorize(self, "\e[1m\e[31m"); end
    def green; colorize(self, "\e[1m\e[32m"); end
    def dark_green; colorize(self, "\e[32m"); end
    def yellow; colorize(self, "\e[1m\e[33m"); end
    def blue; colorize(self, "\e[1m\e[34m"); end
    def dark_blue; colorize(self, "\e[34m"); end
    def pur; colorize(self, "\e[1m\e[35m"); end
    def colorize(text, color_code)  "#{color_code}#{text}\e[0m" end
end

И при использовании

puts "Hello".red

Оставить отзыв

Вы можете использовать простые теги форматирования HTML (вроде <a>, <ul> and others). Чтобы вставить пример код, используйте <code lang="php">$a = "hello";</code> (поддерживаемые языки: ruby, php, yaml, html, csharp, javascript). Также Вы можете использовать <code>$a = "hello";</code>, синтаксис не будет подсвечен. Если вы не хотите использовать тег <code>, замените символ < на &lt;.

Отправить

 
Copyright © 2005 - 2008, Dmytro Shteflyuk