Как определить текущий цвет вывода консоли?

14

Я знаю, что, если имеется цветной терминал, его цвет можно вывести с помощью escape-символов .

Но есть ли возможность узнать, каким цветом вывод отображается в данный момент? Или лучше, какого цвета будет текст, если я выведу его прямо сейчас?

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

Minix
источник
Глядя на переменные termcap и terminfo, кажется, что это невозможно. Например, вы можете получить количество цветов, поддерживаемых вашим терминалом echotc Coили echoti colors, но просто не существует переменной, в которой хранится текущее определение цветового кода.
Джимми
@jimmij Я так и думал и надеялся, что что-то упустил. Если вы достаточно уверены, что это невозможно, тогда ответьте, и я в конечном итоге приму это, если больше ничего не последует. Спасибо за ваше время.
Minix

Ответы:

10

В общем, получение текущих цветов невозможно. Обработка управляющей последовательности терминала происходит «внутри» терминала, где бы это ни происходило. С эмулятором терминала, таким как xtermили встроенный в ядро ​​операционной системы, которое предоставляет виртуальные терминалы ядра, внутреннее состояние эмулятора, включая его представление о текущем «графическом представлении» (то есть цвет и атрибуты), находится на компьютере сам и теоретически доступен. Но для реального терминала эта информация находится в некотором месте ОЗУ на физически отдельной машине, подключенной через последовательный канал.

Тем не менее, некоторые терминалы включают в себя механизм для считывания такой информации как часть их протокола терминала, который отправляется по этой последовательной линии связи. Они предоставляют управляющие последовательности, которые программа может отправлять на терминал, что заставляет ее отправлять обратно информацию о своем внутреннем состоянии, как ввод с терминала. mikeservпоказал последовательности управления, на которые xtermотвечает эмулятор терминала. Но это конкретно для xterm. Например, встроенные эмуляторы терминала в ядре Linux и различных ядрах BSD представляют собой разные типы терминалов и вообще не реализуют никаких таких управляющих последовательностей. То же самое касается целых семей реальных терминалов.

Терминалы DEC VT525 реализуют механизм считывания, но имеют набор последовательностей управления, которые не имеют отношения к тем, которые используются xterm. Один отправляет последовательность DECRQSS (запрос выбора или настройки), чтобы запросить текущее графическое представление, и терминал отвечает отправкой DECRPSS (выбор отчета или настройка). В частности:

  1. Хост отправляет: DCS $ q mST (DECRQSS с частью функции управления SGR в качестве настройки)
  2. Терминал отвечает: DCS 0 $ r 0 ; 3 3 ; 4 4 mST (DECRPSS с параметрами и частью функции управления последовательности управления SGR, которая устанавливает текущие цвета переднего плана и фона)

Конечно, внимательное изучение вашего вопроса показывает, что вы снова махаете бананом в шоколадной оболочке в этих европейских валютных системах. То, что вы на самом деле пытаетесь сделать, для которого вы выбрали решение, а затем спросили, как выполнить часть этого решения, - это сохранить предыдущее состояние, пока вы пишете какой-либо цветовой вывод. Для этого есть не только управляющая последовательность DEC VT, но и последовательность консольных терминалов SCO, которая распознается xtermразличными встроенными в ядро ​​эмуляторами терминалов, и запись termcap / terminfo, которая сообщает вам, что они представляют для вашего терминала.

Записи termcap являются scи rc. Записи terminfo - это save_cursorи restore_cursor. Имена несколько вводят в заблуждение относительно эффекта (хотя они действуют как предупреждение, что вы полагаетесь на что-то де-факто, а не де-юре ). Фактические последовательности управления DECSC, DECRC, SCOSC и SCORC также сохраняют и восстанавливают текущее графическое представление.

Учитывая, что статья, на которую вы указали, посвящена генерации управляющих последовательностей из сценариев оболочки, команда, которую вы сейчас ищете, - это tput.

дальнейшее чтение

JdeBP
источник
Отличный ответ. Рад, что вернулся к этому. Большое спасибо.
Minix
@Minix - помимо scи rc, вы также можете посмотреть в альтернативный буфер, если ваш терминал поддерживает его. И да, это отличный ответ. Minix, может быть, также посмотрите на это: как использовать / dev / fb0 в качестве консоли из пользовательского пространства . noshСвита он рекомендует есть его собственное.
mikeserv
@mikeserv Я посмотрю, спасибо за ссылки :)
Minix
2
Заметил, что это «не имеет никакого отношения к тем, которые используются xterm» - однако xterm довольно долго поддерживал DECRQSS. Часть с ответом SGR, включая цвет датируется 1996 годом.
Томас Дики
2
См. « Дальнейшее чтение» в документации по последовательностям управления xterm, в которой указано, что документация VT520 / etc не была доступна, когда xterm начал предоставлять цвета DECRQSS(с задержкой около 7 лет ...).
Томас Дики
10

В одном xtermвы можете получить текущие цветов RGB цветовых коды сообщенных посредством изменения побега изменения цвета на запрос. Используйте ESC ] Ps m- но добавьте ?знак вопроса. Из документов :

  • Если "?"задано а, а не имя или спецификация RGB, то xtermотвечает контрольной последовательностью той же формы, которую можно использовать для установки соответствующего динамического цвета. Поскольку в одной последовательности управления может быть задано более одной пары номера цвета и спецификации, xtermможно сделать более одного ответа.
    • P s = 1 0 → Изменить основной цвет текста VT100 на P t.
    • P s = 1 1 → Изменить цвет фона текста VT100 на P t.
    • P s = 1 2 → Изменить цвет текстового курсора на P t.
    • P s = 1 3 → Изменить цвет переднего плана мыши на P t.
    • P s = 1 4 → Изменить цвет фона мыши на P t.
    • P s = 1 5 → Изменить цвет переднего плана Tektronix на P t.
    • P s = 1 6 → Изменить цвет фона Tektronix на P t.
    • P s = 1 7 → Изменить цвет фона подсветки на P t.
    • P s = 1 8 → Изменить цвет курсора Tektronix на P t.
    • P s = 1 9 → Изменить цвет переднего плана подсветки на P t.

У меня есть серьезные сомнения, если это будет работать в другом эмуляторе терминала, но xtermесли вы запустите ...

printf '\033]11;?\007'

... команда xtermвернет во входной буфер вашего терминала последовательность, подобную следующей ...

11;rgb:ffff/ffff/ffff

... для фона или для переднего плана:

printf '\033]10;?\007'

10;rgb:0000/0000/0000
mikeserv
источник
Поэтому, когда я бегу printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, весь текст в терминале, который раньше был «нормальным», становился голубым. Впоследствии, бег printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'превращает весь светло-синий текст обратно в «нормальный». Как использовать это значение, чтобы изменить цвет текста только вперед?
четверг в четверг
@fourpastmidnight: может быть, clearсначала?
mikeserv
Я думаю, что я не понимаю документацию. В нем четко сказано «P s = 1 0 -> изменить цвет переднего плана VT100», и, похоже, именно это он и делает. ;) Но это не то, что я ожидал. Мне может понадобиться использовать значение RGB, полученное из "P s = 1 0; Pt =?" с другой сбежавшей командой, чтобы добиться того, чего я хочу.
четверг,
Итак, printf '\033]10;?\007'запрашивает xterm текущий цвет переднего плана терминала. Если ваш терминал был запущен с «нормальным» (например, 7 в качестве цвета переднего плана), но вы запускаете tput setaf 3перед запуском printfкоманды, приведенная printfвыше команда все еще возвращает «нормальный» - и это правильно, потому что это текущий цвет переднего плана вашего терминала. То, на что я надеялся, это способ получить текущий цвет текущей позиции курсора, чтобы я мог сохранить его, чтобы «восстановить» его позже - согласно ОП.
четверг,
1
@fourpastmidnight - вы переходили по ссылке в ответе здесь? Кроме того, Томас Дики - (он прокомментировал другой ответ на этот вопрос) - xtermсопровождающий и активный участник здесь. (ссылка на его веб-сайт - xtermсправочные документы обширные - и в основном стандартная ссылка для любого другого программиста, желающего написать терминал)
mikeserv