Como determinar a cor atual da saída do console?

12

Eu sei que, se um terminal colorido estiver disponível, é possível colorir a saída dele usando caracteres de escape .

Mas existe a possibilidade de descobrir qual cor a saída está sendo exibida atualmente? Ou melhor, qual a cor do texto, se eu fosse produzir agora?

Estou pedindo para não quebrar as configurações de cores anteriores ao usar esses caracteres de escape. O caractere de escape 'cor de primeiro plano padrão' está obtendo informações do esquema de cores, em vez da cor do texto antes de alterá-lo.

    
por Minix 10.12.2014 / 15:04

2 respostas

6

Em geral, obter as cores atuais é impossível. O processamento da sequência de controle de um terminal acontece "dentro" do terminal, onde quer que esteja. Com um terminal emulador como xterm ou o construído em um kernel do sistema operacional que fornece os terminais virtuais do kernel, o estado interno do emulador, incluindo sua noção de "renderização gráfica" atual ( isto é, cor e atributos), está na própria máquina e é teoricamente acessível. Mas para um terminal real esta informação está em algum local de RAM em uma máquina fisicamente separada conectada através de um link serial.

Dito isto, alguns terminais incluem um mecanismo para ler essas informações como parte de seu protocolo terminal, que é enviado através desse link serial. Eles fornecem seqüências de controle que um programa pode enviar para o terminal, fazendo com que ele envie de volta informações sobre seu estado interno, como entrada de terminal. mikeserv mostrou as sequências de controle que o emulador de terminal xterm responde. Mas estes são específicos para xterm . Os emuladores de terminal embutidos no kernel do Linux e os vários kernels BSD são tipos de terminal diferentes, por exemplo, e não implementam nenhuma sequência de controle. O mesmo vale para famílias inteiras de terminais reais.

Os terminais DEC VT525 implementam um mecanismo de leitura, mas possuem um conjunto de seqüências de controle que não tem relação com aquelas usadas por xterm . Um envia a sequência DECRQSS (Solicitar Seleção ou Configuração) para solicitar a execução gráfica atual, e o terminal responde enviando o DECRPSS (Report Selection or Setting). Especificamente:

  1. O host envia: DCS $ q m ST (DECRQSS com a parte da função de controle de SGR como a configuração)
  2. O terminal responde: DCS 0 $ r 0 ; 3 3 ; 4 4 m ST (DECRPSS com os parâmetros e parte da função de controle de uma sequência de controle SGR que define as cores atuais de primeiro plano e plano de fundo)

Claro, uma leitura cuidadosa da sua pergunta revela que você está acenando uma banana coberta de chocolate nesses sistemas monetários europeus novamente. O que você está realmente tentando fazer, para o qual você selecionou uma solução e, em seguida, perguntou como fazer parte dessa solução, é preservar o estado anterior enquanto você escreve alguma saída colorida. Não apenas há uma sequência de controle DEC VT para fazer isso, mas também uma sequência terminal do console SCO para ela, que é reconhecida por xterm e vários emuladores de terminal integrados do kernel, e uma entrada termcap / terminfo que informa para que são seu terminal.

As entradas termcap são sc e rc . As entradas terminfo são save_cursor e restore_cursor . Os nomes são um tanto enganadores quanto ao efeito (embora eles atuem como um aviso de que você está confiando em algo que é de fato ao invés de de jure ). As seqüências de controle DECSC, DECRC, SCOSC e SCORC atuais salvam e restauram a renderização gráfica atual também.

Dado que o artigo que você apontou é sobre como gerar sequências de controle a partir de scripts de shell, o comando que você está agora procurando é tput .

Leitura adicional

por 04.01.2015 / 13:00
9

Em um xterm , você pode obter os códigos de cor RGB atuais relatados alterando uma fuga de mudança de cor para uma consulta. Use o ponto de interrogação ESC ] Ps m - mas adicione um ? . Nos documentos :

  • Se for indicado um "?" em vez de um nome ou uma especificação RGB, xterm responde com uma sequência de controle da mesma forma que pode ser usada para definir a cor dinâmica correspondente. Como mais de um par de números de cores e especificações podem ser fornecidos em uma sequência de controle, xterm pode fazer mais de uma resposta.
    • P s = 1 0 → Altera a cor de primeiro plano do texto VT100 para P t.
    • P s = 1 1 → Altera a cor de fundo do texto VT100 para P t.
    • P s = 1 2 → Altera a cor do cursor de texto para P t.
    • P s = 1 3 → Altere a cor do primeiro plano do mouse para P t.
    • P s = 1 4 → Altere a cor de fundo do mouse para P t.
    • P s = 1 5 → Mude a cor do primeiro plano da Tektronix para P t.
    • P s = 1 6 → Mude a cor de fundo do Tektronix para P t.
    • P s = 1 7 → Altere a cor de fundo realçada para P t.
    • P s = 1 8 → Mude a cor do cursor da Tektronix para P t.
    • P s = 1 9 → Alterar a cor do primeiro plano realçado para P t.

Tenho sérias dúvidas se é provável que isso funcione em outro emulador de terminal, mas em um xterm se você executar ...

printf '3]11;?
11;rgb:ffff/ffff/ffff
7'

... o xterm irá empurrar de volta para o buffer de entrada do seu terminal uma sequência como a seguinte ...

printf '3]10;?
printf '3]11;?
11;rgb:ffff/ffff/ffff
7'
7' 10;rgb:0000/0000/0000

... para o plano de fundo ou para o primeiro plano:

printf '3]10;?%pre%7'

10;rgb:0000/0000/0000
    
por 11.12.2014 / 04:49