How to determine the current color of the console output?

10,082

Solution 1

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

Solution 2

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
Share:
10,082

Related videos on Youtube

Minix
Author by

Minix

Coming from Germany, identifiable by my love, of, commas.

Updated on September 18, 2022

Comments

  • Minix
    Minix over 1 year

    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.

    • jimmij
      jimmij over 9 years
      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.
    • Minix
      Minix over 9 years
      @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
    Minix about 9 years
    Great answer. Glad I went back for it. Thanks a lot.
  • mikeserv
    mikeserv about 9 years
    @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.
  • Minix
    Minix about 9 years
    @mikeserv I'll take a look, thanks for the links :)
  • Marius
    Marius about 9 years
    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.
  • fourpastmidnight
    fourpastmidnight over 8 years
    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?
  • mikeserv
    mikeserv over 8 years
    @fourpastmidnight: maybe clear first?
  • fourpastmidnight
    fourpastmidnight over 8 years
    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
    fourpastmidnight over 8 years
    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
    fourpastmidnight over 8 years
    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.. :)
  • mikeserv
    mikeserv over 8 years
    @fourpastmidnight - did you follow the link in the answer here? also, Thomas Dickey - (he commented on the other answer to this question) is xterm's maintainer and is an active member here. (the link is to his website - xterm's escape docs are extensive - and basically the standard reference for any other programmer wanting to write a terminal)
  • fourpastmidnight
    fourpastmidnight over 8 years
    Yeah, I've been pouring over that the last few hours trying to make sense of it. I think what I just posted about Ps=10;? is correct--and so is the documentation--it's just not what I wanted or expected. Having said that, it could be my terminal, too? ;) Perhaps Mintty is not behaving properly. Thanks for your comments and suggestions!
  • mikeserv
    mikeserv over 8 years
    @fourpastmidnight - the behavior you describe is actually pretty weird, you know.
  • Marius
    Marius over 5 years
    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...).