Come determinare il colore corrente dell'output della console?


14

So che, se è disponibile un terminale colorato, si può colorare l'output di esso usando caratteri di escape .

Ma c'è la possibilità di scoprire in che colore viene attualmente visualizzato l'output? O meglio, di che colore sarebbe il testo, se lo facessi in questo momento?

Sto chiedendo di non rompere alcuna impostazione di colore precedente, quando si usano questi caratteri di escape. Il carattere di escape "colore di primo piano predefinito" sta ottenendo le informazioni dalla combinazione di colori, piuttosto che dal colore del testo prima di modificarlo.


Osservando le variabili termcap e terminfo sembra che non sia possibile. Ad esempio, è possibile ottenere il numero di colori supportati dal proprio terminale con echotc Coo echoti colors, ma semplicemente non esiste alcuna variabile che memorizzi l'attuale definizione del codice colore.
Jimmij,

@jimmij L'ho pensato così e speravo che mi mancasse qualcosa. Se sei abbastanza sicuro che non sia possibile, allora fagli una risposta e alla fine lo accetterò, se nient'altro segue. Grazie per il tuo tempo.
Minix,

Risposte:


10

In generale, ottenere i colori attuali è impossibile. L'elaborazione della sequenza di controllo di un terminale avviene "all'interno" del terminale, ovunque si trovi. Con un emulatore di terminale come xtermo quello incorporato in un kernel del sistema operativo che fornisce i terminali virtuali del kernel, lo stato interno dell'emulatore, inclusa la sua nozione dell'attuale "rappresentazione grafica" (cioè colore e attributi), è sulla macchina stesso ed è teoricamente accessibile. Ma per un terminale reale questa informazione si trova in una posizione della RAM su una macchina fisicamente separata connessa tramite un collegamento seriale.

Detto questo, alcuni terminali includono un meccanismo per leggere tali informazioni come parte del loro protocollo terminale, che viene inviato tramite quel collegamento seriale. Forniscono sequenze di controllo che un programma può inviare al terminale, che gli fanno inviare informazioni sul suo stato interno, come input del terminale. mikeservti ha mostrato le sequenze di controllo a cui l' xtermemulatore di terminale risponde. Ma questi sono specifici di xterm. Gli emulatori di terminali integrati nel kernel Linux e i vari kernel BSD sono diversi tipi di terminali, ad esempio, e non implementano affatto tali sequenze di controllo. Lo stesso vale per intere famiglie di terminali reali.

I terminali DEC VT525 implementano un meccanismo di lettura, ma hanno una serie di sequenze di controllo che non hanno alcuna relazione con quelle utilizzate da xterm. Uno invia la sequenza DECRQSS (Richiedi selezione o impostazione) per richiedere la rappresentazione grafica corrente e il terminale risponde inviando il DECRPSS (Selezione o impostazione rapporto). In particolare:

  1. L'host invia: DCS $ q mST (DECRQSS con la funzione di controllo parte di SGR come impostazione)
  2. Il terminale risponde: DCS 0 $ r 0 ; 3 3 ; 4 4 mST (DECRPSS con i parametri e la funzione di controllo parte di una sequenza di controllo SGR che imposta i colori di primo piano e di sfondo correnti)

Naturalmente, un'attenta lettura della tua domanda rivela che stai agitando di nuovo una banana ricoperta di cioccolato in quei sistemi monetari europei. Quello che stai effettivamente cercando di fare, per il quale hai selezionato una soluzione e poi chiesto come fare parte di quella soluzione, è preservare lo stato precedente mentre scrivi un output colorato. Non solo esiste una sequenza di controllo DEC VT per fare questo, c'è una sequenza terminale della console SCO per essa riconosciuta da xtermvari emulatori di terminali incorporati nel kernel e una voce termcap / terminfo che ti dice cosa sono per il tuo terminale.

Le voci termcap sono sce rc. Le voci terminfo sono save_cursore restore_cursor. I nomi sono in qualche modo fuorvianti per quanto riguarda l'effetto (anche se fungono da avvertimento che stai facendo affidamento su qualcosa che è di fatto piuttosto che di diritto ). Le sequenze di controllo DECSC, DECRC, SCOSC e SCORC effettive salvano e ripristinano anche la rappresentazione grafica corrente.

Dato che l'articolo che hai indicato riguarda la generazione di sequenze di controllo dagli script di shell, il comando che stai cercando ora è tput.

Ulteriori letture


Bella risposta. Sono contento di esserci tornato. Molte grazie.
Minix,

@Minix - oltre sce rc, si potrebbe anche voler guardare nel buffer alternativo se supportato dal terminale IT. E sì, questa è un'ottima risposta. Minix, forse guarda anche questo: come usare / dev / fb0 come console dallo spazio utenti . La noshsuite che raccomanda è la sua.
Mikeserv,

@mikeserv darò un'occhiata, grazie per i collegamenti :)
Minix,

2
Ho notato che "non ha alcuna relazione con quelli usati da xterm" - tuttavia, DECRQSS ha supportato xterm per un bel po '. La parte con risposta SGR incluso il colore risale al 1996.
Thomas Dickey,

2
Vedi ulteriori letture , nella documentazione sulle sequenze di controllo di xterm, che sottolinea che la documentazione VT520 / etc non era disponibile quando xterm ha iniziato a fornire i colori DECRQSS(con un ritardo di circa 7 anni ...).
Thomas Dickey,

10

In un xtermè possibile ottenere i codici colore RGB di colore correnti riportati modificando una fuga di cambio colore a una query. Usa il ESC ] Ps m- ma aggiungi un ?punto interrogativo. Dai documenti :

  • Se "?"viene dato un carattere anziché un nome o una specifica RGB, xtermrisponde con una sequenza di controllo della stessa forma che può essere utilizzata per impostare il colore dinamico corrispondente. Poiché è possibile fornire più di una coppia di numeri di colore e specifiche in una sequenza di controllo, è xtermpossibile effettuare più di una risposta.
    • P s = 1 0 → Cambia il colore di primo piano del testo VT100 in P t.
    • P s = 1 1 → Cambia il colore di sfondo del testo VT100 in P t.
    • P s = 1 2 → Cambia il colore del cursore di testo in P t.
    • P s = 1 3 → Cambia il colore di primo piano del mouse in P t.
    • P s = 1 4 → Cambia il colore di sfondo del mouse in P t.
    • P s = 1 5 → Cambia il colore di primo piano di Tektronix in P t.
    • P s = 1 6 → Cambia il colore di sfondo di Tektronix in P t.
    • P s = 1 7 → Cambia il colore di sfondo dell'evidenziazione in P t.
    • P s = 1 8 → Cambia il colore del cursore Tektronix in P t.
    • P s = 1 9 → Cambia il colore di primo piano di evidenziazione in P t.

Ho seri dubbi sul fatto che questo funzioni probabilmente in un altro emulatore di terminale, ma in un xtermcaso in cui esegui ...

printf '\033]11;?\007'

... xtermtornerà nel buffer di input del tuo terminale una sequenza come la seguente ...

11;rgb:ffff/ffff/ffff

... per lo sfondo o per il primo piano:

printf '\033]10;?\007'

10;rgb:0000/0000/0000

Quindi, quando corro printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, tutto il testo nel terminale precedentemente "normale" diventa blu chiaro. Successivamente, la corsa printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'riporta tutto il testo azzurro su "normale". Come posso usare questo valore per cambiare solo il colore del testo andando avanti?
fourpastmidnight,

@fourpastmidnight: forse clearprima?
Mikeserv,

Sto pensando di non capire la documentazione. Dice chiaramente "P s = 1 0 -> cambia il colore di primo piano VT100", e beh, questo è ciò che sembra fare. ;) Ma non è quello che mi aspettavo. Potrebbe essere necessario utilizzare il valore RGB recuperato da "P s = 1 0; Pt =?" con un altro comando evaso per ottenere ciò che voglio.
fourpastmidnight,

Ok, quindi printf '\033]10;?\007'interroga xterm per l'attuale colore di primo piano del terminale. Se il tuo terminale è stato avviato con "normale" (ad esempio 7 come colore di primo piano), ma esegui tput setaf 3prima di eseguire il printfcomando, il printfcomando sopra restituisce comunque "normale" - ed è giusto, perché quello è il colore di primo piano corrente del tuo terminale. Quello che speravo era un modo per recuperare il colore corrente della posizione corrente del cursore in modo da poterlo salvare per "ripristinarlo" in un secondo momento, come per l'OP.
fourpastmidnight,

1
@fourpastmidnight - hai seguito il link nella risposta qui? inoltre, Thomas Dickey - (ha commentato l'altra risposta a questa domanda) è xtermil manutentore ed è un membro attivo qui. (il link è al suo sito web - xtermi documenti di escape sono estesi - e sostanzialmente il riferimento standard per qualsiasi altro programmatore che voglia scrivere un terminale)
mikeserv
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.