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

14

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

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

Estou pedindo para não quebrar nenhuma configuração de cor anterior 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 eu a alterar.

Minix
fonte
Olhando para as variáveis ​​termcap e terminfo, parece que não é possível. Você pode, por exemplo, obter o número de cores que seu terminal suporta com echotc Coou echoti colors, mas simplesmente não existe uma variável que armazene a definição atual do código de cores.
jimmij
@ jimmij Eu pensava assim e estava esperando, que eu perdesse alguma coisa. Se você tem certeza de que isso não é possível, faça uma resposta e eu a aceitarei eventualmente, se nada mais acontecer. Obrigado pelo seu tempo.
Minix

Respostas:

10

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

Dito isto, alguns terminais incluem um mecanismo para ler essas informações como parte de seu protocolo de terminal, que é enviado através desse link serial. Eles fornecem sequências de controle que um programa pode enviar para o terminal, que faz com que ele retorne informações sobre seu estado interno, como entrada do terminal. mikeservmostrou as seqüências de controle às quais o xtermemulador de terminal responde. Mas estes são específicos para xterm. Os emuladores de terminal integrados no kernel Linux e os vários kernels BSD são diferentes tipos de terminal, por exemplo, e não implementam nenhuma dessas seqüências 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 têm relação com as utilizadas por xterm. Um envia a sequência DECRQSS (Solicitar seleção ou configuração) para solicitar a representação gráfica atual e o terminal responde enviando o DECRPSS (Seleção ou configuração de relatório). Especificamente:

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

Obviamente, uma leitura cuidadosa da sua pergunta revela que você está sacudindo uma banana com cobertura de chocolate nos sistemas monetários europeus novamente. O que você está realmente tentando fazer, para o qual você selecionou uma solução e depois perguntou como fazer parte dessa solução, é preservar o estado anterior enquanto você escreve alguma saída colorida. Não apenas existe uma sequência de controle DEC VT para fazer isso, mas também uma sequência de terminal do console SCO que é reconhecida por xtermvários emuladores de terminal integrados ao kernel e uma entrada termcap / terminfo que informa o que eles são para o seu terminal.

As entradas do termcap são sce rc. As entradas terminfo são save_cursore 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, e não de jure ). As seqüências de controle DECSC, DECRC, SCOSC e SCORC atuais também salvam e restauram a representação gráfica atual.

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

Leitura adicional

JdeBP
fonte
Ótima resposta. Ainda bem que voltei para ele. Muito obrigado.
Minix
@Minix - além de sce rc, você também pode querer procurar no buffer alternativo se o seu terminal suportar. E sim, esta é uma ótima resposta. Minix, talvez também veja isto: como usar / dev / fb0 como um console no espaço do usuário . A noshsuíte que ele recomenda é a dele.
mikeserv
@mikeserv eu vou dar uma olhada, graças às ligações :)
Minix
2
Percebeu que isso "não tem relação com os usados ​​pelo xterm" - no entanto, o DECRQSS do xterm é suportado por um bom tempo. A parte com resposta do SGR, incluindo as datas das cores até 1996.
Thomas Dickey
2
Consulte Leitura Adicional , na documentação de seqüências de controle do xterm, que indica que a documentação do VT520 / etc não estava disponível quando o xterm começou a fornecer cores DECRQSS(atraso de aproximadamente 7 anos ...).
Thomas Dickey
10

Em um xtermé possível obter os códigos de cores RGB atuais relatados alterando um escape de alteração de cor para uma consulta. Use o ESC ] Ps m- mas adicione um ?ponto de interrogação. Dos documentos :

  • Se a "?"for fornecido em vez de um nome ou especificação RGB,xterm responde com uma sequência de controle do mesmo formulário que pode ser usada para definir a cor dinâmica correspondente. Como mais de um par de número de cores e especificação pode ser fornecido em uma sequência de controle, é xtermpossível fazer mais de uma resposta.
    • P s = 1 0 → Altere a cor do primeiro plano do texto VT100 para P t.
    • P s = 1 1 → Altere a cor de fundo do texto VT100 para P t.
    • P s = 1 2 → Altere 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 → Altere a cor do primeiro plano do Tektronix para P t.
    • P s = 1 6 → Altere a cor de fundo do Tektronix para P t.
    • P s = 1 7 → Altere a cor do fundo de destaque para P t.
    • P s = 1 8 → Altere a cor do cursor Tektronix para P t.
    • P s = 1 9 → Altere a cor do primeiro plano de destaque para P t.

Tenho sérias dúvidas se isso provavelmente funcionará em outro emulador de terminal, mas em um xtermse você executar ...

printf '\033]11;?\007'

... xtermempurrará de volta para o buffer de entrada do terminal uma sequência como a seguinte ...

11;rgb:ffff/ffff/ffff

... em segundo plano ou em primeiro plano:

printf '\033]10;?\007'

10;rgb:0000/0000/0000
mikeserv
fonte
Então, quando eu corro printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, todo o texto no terminal que antes era "normal" ficava em azul claro. Posteriormente, a execução printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'retorna todo o texto azul claro para "normal". Como uso esse valor para alterar apenas a cor do texto no futuro?
Fourpastmidnight 15/11/2015
@ fourpastmidnight: talvez clearprimeiro?
mikeserv
Estou pensando que não estou entendendo a documentação. Diz claramente "P s = 1 0 -> altere a cor do primeiro plano do VT100" e, bem, é isso que parece estar fazendo. ;) Mas não era o que eu esperava. Talvez eu precise usar o valor RGB recuperado de "P s = 1 0; Pt =?" com outro comando escapado para alcançar o que eu quero.
Fourpastmidnight 15/11/2015
Ok, então printf '\033]10;?\007'consulta xterm para ver a cor atual do primeiro plano do terminal. Se o seu terminal foi iniciado com "normal" (por exemplo, 7 como a cor do primeiro plano), mas você executa tput setaf 3antes de executar o printfcomando, o printfcomando acima ainda retorna "normal" - e está certo, porque essa é a cor atual do primeiro plano do seu terminal. O que eu esperava era uma maneira de recuperar a cor atual da posição atual do cursor para que eu pudesse salvá-la para "restaurá-la" mais tarde - conforme o OP.
Fourpastmidnight 15/11/2015
1
@fourpastmidnight - você seguiu o link na resposta aqui? também Thomas Dickey - (ele comentou a outra resposta a esta pergunta) é xtermo mantenedor e é um membro ativo aqui. (o link é para o seu website - xterm's docs de fuga são extensos - e, basicamente, a referência padrão para qualquer outro programador querendo escrever um terminal)
mikeserv