Как я могу передать с терминала в Perl, не теряя цвет? - PullRequest
3 голосов
/ 22 февраля 2011

Я пытаюсь написать Perl-скрипт, который принимает вывод colorgcc (или любой другой скрипт, который печатает цветной текст на терминал), добавляет / удаляет части строки, а затем печатает результат в том же цвет в качестве входной строки.

Следующий код будет печатать «Hello World» перед каждой строкой, созданной color_proroduction_script . Выход будет полностью черным, а вход - многоцветным. Как я могу изменить этот скрипт, чтобы сохранить исходные цвета?

open(CMD, "color_producing_script |");

while(<CMD>) {
    print 'Hello World' . $_;
}

Я использую bash терминал.

Редактировать

Согласно первоклассному первому комментарию, это не проблема Perl как таковая. Просто запуск color_producing_script | cat снимает цвет. Таким образом, вопрос можно перефразировать так: «Как вы проталкиваете цвет через трубу?»

Редактировать 2

Похоже, что последняя версия gcc (1.3.2) включает переменную среды CGCC_FORCE_COLOR в предложении if, и, если она определена, colorgcc вызывает color:

export CGCC_FORCE_COLOR=true

Ответы [ 3 ]

4 голосов
/ 22 февраля 2011

Меняет ли color_producing_script свое поведение при использовании в трубе? Попробуйте

color_producing_script | cat

в командной строке. Может иметь опцию принудительного вывода цвета, даже если это так.

Скрипт Perl, colorgcc, специально проверяет, является ли вывод не-tty, и пропускает раскраску, если это так.

# Get the terminal type. 
$terminal = $ENV{"TERM"} || "dumb";

# If it's in the list of terminal types not to color, or if
# we're writing to something that's not a tty, don't do color.
if (! -t STDOUT || $nocolor{$terminal})
{
   exec $compiler, @ARGV
      or die("Couldn't exec");
}

Edit:

Вы можете изменить скрипт одним или несколькими из следующих способов:

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

Вы также можете использовать сценарий expect unbuffer для создания псевдо-tty, подобного этому:

unbuffer gcc file.c | cat

(где cat - обычный получатель).

Все это основано на использовании colorgcc из командной строки. В скрипте Perl должны быть аналоги для подобных действий.

3 голосов
/ 22 февраля 2011

Исходный код ColorGCC достаточно ясен по этой теме!

#! /usr/bin/perl -w
# ...
# from: colorgcc-4.1.2/colorgcc-4.1.2
# downloaded from: http://www.console-colors.de/index.php?n=ConsColors.Downloads
#
# Note:
#
# colorgcc will only emit color codes if:
# 
#    (1) Its STDOUT is a tty and
#    (2) the value of $TERM is not listed in the "nocolor" option.
#
# If colorgcc colorizes the output, the compiler's STDERR will be
# combined with STDOUT. Otherwise, colorgcc just passes the output from
# the compiler through without modification.
# .....
# If it's in the list of terminal types not to color, or if
# we're writing to something that's not a tty, don't do color.
if (! -t STDOUT || $nocolor{$terminal})
{
   exec $compiler, @ARGV
      or die("Couldn't exec");
}

В дополнение к использованию Pty вместо канала в Perl (как уже указывалось в cjm), вы можете заставить приложение думать, что его стандартный ввод интерактивный, а не канал в командной строке.

Например:

# Linux
script -c "[executable string]" /dev/null

# FreeBSD, Mac OS X
script -q /dev/null "[executable string]"

Дальнейшие решения см .: bash: принудительное выполнение exec'd для вывода буфера без буферизации

3 голосов
/ 22 февраля 2011

Многие программы, которые генерируют цветной вывод, обнаруживают, пишут ли они в TTY, и отключают цвета, если это не так.Это связано с тем, что цветовые коды раздражают, когда вы хотите захватить только текст, поэтому они пытаются автоматически «делать правильные вещи».

Самый простой способ получения цветного вывода из программы, подобной этой, - это сказать это.писать цвет, даже если он не подключен к TTY.Вам нужно будет прочитать документацию программы, чтобы узнать, есть ли у нее эта опция.

Другой вариант - использовать Pty вместо канала.В Perl вы можете сделать это с помощью IO :: Pty :: HalfDuplex или IO :: Pty :: Easy , оба из которых являются обертками более высокого уровня вокруг модуля низкого уровня IO :: Pty .

...