22

I'd like to know if there is any way to determine a terminal's background color ?

In my case, using gnome-terminal.
It might matter, since it's entirety up to the terminal application to draw the background of its windows, which may even be something else than a plain color.

Chris Stryczynski
  • 19,899
  • 28
  • 104
  • 198
Romuald Brunet
  • 4,605
  • 2
  • 32
  • 32

5 Answers5

16

There's an xterm control sequence for this:

\e]11;?\a

(\e and \a are the ESC and BEL characters, respectively.)

Xterm-compatible terminals should reply with the same sequence, with the question mark replaced by an X11 color name, e.g. rgb:0000/0000/0000 for black.

efdee
  • 2,251
  • 3
  • 20
  • 26
ak2
  • 6,262
  • 27
  • 23
  • 7
    Some information on how to utilize this would be an excellent addition. (For instance, a snippet of shell-script that prints a word in a different foreground colour depending on the shell's background colour?) – ELLIOTTCABLE Feb 10 '15 at 00:52
  • (Also, I suspect this will only obtain the background colour *for the text*, if one is shut. Not the background-colour of the actual terminal window, which I suspect is still unobtainable outside of `rxvt`.) – ELLIOTTCABLE Feb 10 '15 at 01:00
  • 3
    In Mac 10.10.4, this (and @blueyed's similar answer) doesn't seem to work in Apple Terminal (which identifies itself as xterm-color), but does work in regular xterm. – TextGeek Jul 29 '15 at 16:44
  • On my system (Ubuntu 15.10), this works with xterm and GNOME Terminal 3.16.2, but not with MATE Terminal 1.10.1. – Martin von Wittich Jun 04 '16 at 19:32
  • @ELLIOTTCABLE This definitely gets the background of the terminal window. It's in the linked page: *"Ps = 1 1 -> Change VT100 text background color to Pt."* and *"For colors and font, if Pt is a "?", the control sequence elicits a response which consists of the control sequence which would set the corresponding value."* – wjandrea Oct 25 '18 at 01:55
10

I've came up with the following:

#!/bin/sh
#
# Query a property from the terminal, e.g. background color.
#
# XTerm Operating System Commands
#     "ESC ] Ps;Pt ST"

oldstty=$(stty -g)

# What to query?
# 11: text background
Ps=${1:-11}

stty raw -echo min 0 time 0
# stty raw -echo min 0 time 1
printf "\033]$Ps;?\033\\"
# xterm needs the sleep (or "time 1", but that is 1/10th second).
sleep 0.00000001
read -r answer
# echo $answer | cat -A
result=${answer#*;}
stty $oldstty
# Remove escape at the end.
echo $result | sed 's/[^rgb:0-9a-f/]\+$//'

Source/Repo/Gist: https://gist.github.com/blueyed/c8470c2aad3381c33ea3

blueyed
  • 24,971
  • 4
  • 72
  • 70
4

Some links:

E.g. some related snippet from Neovim issue 2764:

/*
 * Return "dark" or "light" depending on the kind of terminal.
 * This is just guessing!  Recognized are:
 * "linux"         Linux console
 * "screen.linux"   Linux console with screen
 * "cygwin"        Cygwin shell
 * "putty"         Putty program
 * We also check the COLORFGBG environment variable, which is set by
 * rxvt and derivatives. This variable contains either two or three
 * values separated by semicolons; we want the last value in either
 * case. If this value is 0-6 or 8, our background is dark.
 */
static char_u *term_bg_default(void)
{
  char_u      *p;

  if (STRCMP(T_NAME, "linux") == 0
      || STRCMP(T_NAME, "screen.linux") == 0
      || STRCMP(T_NAME, "cygwin") == 0
      || STRCMP(T_NAME, "putty") == 0
      || ((p = (char_u *)os_getenv("COLORFGBG")) != NULL
          && (p = vim_strrchr(p, ';')) != NULL
          && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
          && p[2] == NUL))
    return (char_u *)"dark";
  return (char_u *)"light";
}

About COLORFGBG env, from Gnome BugZilla 733423:

Out of quite a few terminals I've just tried on linux, only urxvt and konsole set it (the ones that don't: xterm, st, terminology, pterm). Konsole and Urxvt use different syntax and semantics, i.e. for me konsole sets it to "0;15" (even though I use the "Black on Light Yellow" color scheme - so why not "default" instead of "15"?), whereas my urxvt sets it to "0;default;15" (it's actually black on white - but why three fields?). So in neither of these two does the value match your specification.

This is some own code I'm using (via):

def is_dark_terminal_background():
    """
    :return: Whether we have a dark Terminal background color, or None if unknown.
        We currently just check the env var COLORFGBG,
        which some terminals define like "<foreground-color>:<background-color>",
        and if <background-color> in {0,1,2,3,4,5,6,8}, then we have some dark background.
        There are many other complex heuristics we could do here, which work in some cases but not in others.
        See e.g. `here <https://stackoverflow.com/questions/2507337/terminals-background-color>`__.
        But instead of adding more heuristics, we think that explicitly setting COLORFGBG would be the best thing,
        in case it's not like you want it.
    :rtype: bool|None
    """
    if os.environ.get("COLORFGBG", None):
        parts = os.environ["COLORFGBG"].split(";")
        try:
            last_number = int(parts[-1])
            if 0 <= last_number <= 6 or last_number == 8:
                return True
            else:
                return False
        except ValueError:  # not an integer?
            pass
    return None  # unknown (and bool(None) == False, i.e. expect light by default)
Albert
  • 57,395
  • 54
  • 209
  • 347
  • Special thanks for the tip on $COLORFGBG. It works on iTerm2 at least. Very straight forward way to get the background color of an iTerm2 session. +1 – hraban Mar 30 '21 at 19:25
1

Aside from apparently rxvt-only $COLORFGBG, I am not aware that anything else even exists. Mostly people seem to be referring to how vim does it, and even that is an educated guess at best.

Albert
  • 57,395
  • 54
  • 209
  • 347
lkraav
  • 2,438
  • 3
  • 24
  • 25
-1

Do you mean a method to ascertain the terminal background colour, or set the terminal colour?

If the latter you could query your terminal's PS1 environment variable to obtain the colour.

There's an article on setting (and so deriving) the terminal colours here: http://www.ibm.com/developerworks/linux/library/l-tip-prompt/

goose_wh
  • 77
  • 1
  • 3
  • I mean to ascertain the background color. Not the color used to print characters (using escape codes), but the of window itself. Nice article however :) – Romuald Brunet Mar 24 '10 at 13:19