How to determine a terminal's background color?
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 plai开发者_如何学Cn color.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.
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
Some links:
- Xterm escape code:
- http://www.talisman.org/~erlkonig/documents/xterm-color-queries/
- https://invisible-island.net/xterm/ctlseqs/ctlseqs.html (dynamic colors / Request Termcap/Terminfo String)
- http://thrysoee.dk/xtermcontrol/ (
xtermcontrol --get-bg
) - https://gist.github.com/blueyed/c8470c2aad3381c33ea3
- https://github.com/rocky/bash-term-background/blob/master/term-background.sh
COLORFGBG
environment variable (used by Rxvt but not many others...):
It is set to sth like<foreground-color>:[<other-setting>:]<background-color>
, (<other setting>:
is optional), and if<background-color>
in {0,1,2,3,4,5,6,8}, then we have some dark background.- Vim:
- code: https://github.com/vim/vim/blob/05c00c038bc16e862e17f9e5c8d5a72af6cf7788/src/option.c#L3974
- How does Vim guess background color on xterm?
- Emacs... (background-mode) (I think it uses the escape code)
- Related questions / reports / discussions:
- Is there a way to determine a terminal's background color?
- How does Vim guess background color on xterm?
- https://unix.stackexchange.com/questions/245378/common-environment-variable-to-set-dark-or-light-terminal-background
- https://bugzilla.gnome.org/show_bug.cgi?id=733423
- https://github.com/neovim/neovim/issues/2764
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)
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.
As other's have mentioned, you may use OSC 11 ?
to query the terminal (although support varies).
In bash and gnome-terminal:
read -rs -d \\ -p $'\e]11;?\e\\' BG
echo "$BG" | xxd
00000000: 1b5d 3131 3b72 6762 3a30 3030 302f 3262 .]11;rgb:0000/2b
00000010: 3262 2f33 3633 361b 0a 2b/3636..
Note that Bash has some nice features for this (eg read -s
disabling echo, $''
strings for escape codes), but it unfortunately eats the final backslash.
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/
精彩评论