12

I know that, if a coloured terminal is available, one can colour the output of it using escape characters.

But is there a possibility to find out, which colour the output is currently being displayed as? Or better, what colour the text would be, if I would output it right now?

I'm asking to not break any previous colour settings, when using these escape characters. The 'default foreground colour' escape character is getting it's information from the colour scheme, rather than the text colour before I changed it.

  • Looking at termcap and terminfo variables it seems that it is not possible. You can for example get number of colors that your terminal supports with echotc Co or echoti colors, but there is simply no variable which stores current color code definition. – jimmij Dec 10 '14 at 21:28
  • @jimmij I thought so and was hoping, that I missed something. If you are sure enough about it not being possible, then make it an answer and I will eventually accept it, if nothing else follows. Thanks for your time. – Minix Dec 10 '14 at 21:39
6

In general, obtaining the current colours is impossible. The control sequence processing of a terminal happens "inside" the terminal, wherever that happens to be. With a terminal emulator such as xterm or the one built into an operating system kernel that provides the kernel virtual terminals, the internal state of the emulator, including its notion of the current "graphic rendition" (i.e. colour and attributes), is on the machine itself and is theoretically accessible. But for a real terminal this information is in some RAM location on a physically separate machine connected via a serial link.

That said, some terminals include a mechanism for reading out such information as part of their terminal protocol, that is sent over that serial link. They provide control sequences that a program can send to the terminal, that cause it to send back information about its internal state, as terminal input. mikeserv has shown you the control sequences that the xterm terminal emulator responds to. But these are specific to xterm. The built-in terminal emulators in the Linux kernel and the various BSD kernels are different terminal types, for example, and don't implement any such control sequences at all. The same goes for whole families of real terminals.

DEC VT525 terminals implement a read-out mechanism, but have a set of control sequences that bears no relationship to those used by xterm. One sends the DECRQSS (Request Selection or Setting) sequence to request the current graphic rendition, and the terminal responds by sending the DECRPSS (Report Selection or Setting). Specifically:

  1. Host sends: DCS $ q m ST (DECRQSS with the control function part of SGR as the setting)
  2. Terminal responds: DCS 0 $ r 0 ; 3 3 ; 4 4 m ST (DECRPSS with the parameters and control function part of an SGR control sequence that sets the current foreground and background colours)

Of course, a careful reading of your question reveals that you are waving a chocolate-covered banana at those European currency systems again. What you're actually trying to do, for which you've selected a solution and then asked how to do part of that solution, is preserve the previous state whilst you write some colourized output. Not only is there a DEC VT control sequence for doing this, there's a SCO console terminal sequence for it that is recognized by xterm and various kernel built-in terminal emulators, and a termcap/terminfo entry that tells you what they are for your terminal.

The termcap entries are sc and rc. The terminfo entries are save_cursor and restore_cursor. The names are somewhat misleading as to effect (although they do act as a warning that you are relying upon something that is de facto rather than de jure). The actual DECSC, DECRC, SCOSC, and SCORC control sequences save and restore the current graphic rendition as well.

Given that the article that you pointed to is all about generating control sequences from shell scripts, the command that you are now looking for is tput.

Further reading

  • Great answer. Glad I went back for it. Thanks a lot. – Minix Feb 20 '15 at 13:46
  • @Minix - besides sc and rc, you might also want to look into the alternate buffer if your terminal supports it. And yes, this is a great answer. Minix, maybe also look at this: how to use /dev/fb0 as a console from userspace. The nosh suite he recommends there is his own. – mikeserv Feb 20 '15 at 15:46
  • @mikeserv I'll take a look, thanks for the links :) – Minix Feb 22 '15 at 9:38
  • 2
    Noticed this "bears no relationship to those used by xterm" -- however, xterm's supported DECRQSS for quite a while. The part with SGR response including color dates to 1996. – Thomas Dickey Mar 29 '15 at 1:24
  • 1
    See Further Reading, in xterm's control-sequences documentation, which points out that the VT520/etc documentation was not available when xterm started providing colors in DECRQSS (about 7 years delay...). – Thomas Dickey Feb 2 at 20:23
9

In an xterm you can get the current color RGB color codes reported by altering a color change escape to a query. Use the ESC ] Ps m - but add a ? question mark. From the docs:

  • If a "?" is given rather than a name or RGB specification, xterm replies with a control sequence of the same form which can be used to set the corresponding dynamic color. Because more than one pair of color number and specification can be given in one control sequence, xterm can make more than one reply.
    • P s = 1 0 → Change VT100 text foreground color to P t .
    • P s = 1 1 → Change VT100 text background color to P t .
    • P s = 1 2 → Change text cursor color to P t .
    • P s = 1 3 → Change mouse foreground color to P t .
    • P s = 1 4 → Change mouse background color to P t .
    • P s = 1 5 → Change Tektronix foreground color to P t .
    • P s = 1 6 → Change Tektronix background color to P t .
    • P s = 1 7 → Change highlight background color to P t .
    • P s = 1 8 → Change Tektronix cursor color to P t .
    • P s = 1 9 → Change highlight foreground color to P t .

I have serious doubts if this is likely to work in another terminal emulator, but in an xterm if you run...

printf '\033]11;?\007'

...the xterm will push back into your terminal's input buffer a sequence like the following...

11;rgb:ffff/ffff/ffff

...for the background or for the foreground:

printf '\033]10;?\007'

10;rgb:0000/0000/0000
  • So when I run printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, all text in the terminal that was previously "normal" turned to a light blue. Subsequently, running printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007' turns all the light blue text back to "normal". How do I use this value to only change the color of the text moving forward? – fourpastmidnight Nov 15 '15 at 4:57
  • @fourpastmidnight: maybe clear first? – mikeserv Nov 15 '15 at 4:59
  • I'm thinking I'm not understanding the documentation. It does clearly say "P s = 1 0 -> change VT100 foreground color", and well, that's what it appears to be doing. ;) But that's not what I expected. I might need to use the RGB value retrieved from "P s = 1 0; Pt = ?" with another escaped command to achieve what I want. – fourpastmidnight Nov 15 '15 at 5:02
  • Ok, so printf '\033]10;?\007' queries xterm for the terminal's current foreground color. If your terminal was started with "normal" (e.g. 7 as the foreground color), but you run tput setaf 3 before running the printf command, the printf command above still returns "normal"--and that's right, because that's your terminal's current foreground color. What I was hoping for was a way to retrieve the current color of the current cursor position so I could save it off to "restore" it later--as per the OP. – fourpastmidnight Nov 15 '15 at 5:08
  • Oh, and, about saving off the current color of the current cursor position, yeah, I already have seen the "save cursor"/"restore cursor" hack that seems to be a popular "solution" to this problem. Oh well.. :) – fourpastmidnight Nov 15 '15 at 5:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.