Як визначити поточний колір виходу консолі?


14

Я знаю, що якщо є кольоровий термінал, можна пофарбувати висновок його за допомогою символів втечі .

Але чи є можливість дізнатися, який колір відображається в даний момент? Або краще, якого б кольору був текст, якби я вийшов зараз?

Я прошу не порушувати жодних попередніх налаштувань кольору під час використання цих символів. Символ виходу "колір переднього плану" за замовчуванням отримує інформацію про кольорову схему, а не про колір тексту, перш ніж я змінив його.


Переглядаючи змінні termcap та terminfo, здається, що це неможливо. Наприклад , ви можете отримати кількість квітів , що ваш термінал підтримує з echotc Coабо echoti colors, але там просто не змінна , яка зберігає поточний колір визначення коду.
jimmij

@jimmij Я так думав і сподівався, що я щось пропустив. Якщо ви досить впевнені, що це неможливо, то зробіть це відповіддю, і я, зрештою, прийму це, якщо нічого іншого не випливає. Дякую за ваш час.
Minix

Відповіді:


11

Взагалі отримати нинішні кольори неможливо. Обробка контрольної послідовності терміналу відбувається "всередині" терміналу, де б це не було. З термінальним емулятором, таким як 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.

Подальше читання


Чудова відповідь. Радий, що я повернувся за цим. Дуже дякую.
Мінікс

@Minix - крім того , scі rcви також можете подивитися в альтернативний буфер , якщо ваш термінал підтримує. І так, це чудова відповідь. Minix, можливо, також подивіться на це: як використовувати / dev / fb0 як консоль з простору користувачів . noshСвита він рекомендує їсти його власне.
mikeserv

@mikeserv Я погляну, дякую за посилання :)
Minix

2
Помітив, що це "не має стосунку до тих, які використовує xterm" - проте, xterm підтримував DECRQSS досить довгий час. Частина з відповіддю СГР, включаючи колір, датується 1996 роком.
Томас Дікі

2
Див. Подальше читання у документації про послідовності контролю xterm, де вказується, що документація VT520 / тощо не була доступна, коли 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

Тож коли я запускаю 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
док-файли для
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.