The email back from Thomas Dickey (xterm's maintainer) has this. Note in particular the part about ?
. The Ps = 4
refers to OSC Ps ; Pt ST
where OSC
(the "Operating System Control" prefix) is ESC ]
and ST
(the "String Terminator" suffix) is \
(backslash). The 4
is one of the possible subcommands to OSC.
For the whole palette, that can be set/retrieved using the 88/256 color
extension. In ctlseqs.txt, it's summarized here:
Ps = 4 ; c ; spec -> Change Color Number c to the color
specified by spec. This can be a name or RGB specification as
per XParseColor. Any number of c/spec pairs may be given.
The color numbers correspond to the ANSI colors 0-7, their
bright versions 8-15, and if supported, the remainder of the
88-color or 256-color table.
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 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.
A bit later in the docs are more OSC subcommands, Ps = 10
and Ps = 11
, and others.
Ps = 1 0 -> Change VT100 text foreground color to Pt.
Ps = 1 1 -> Change VT100 text background color to Pt.
Example - this queries the background using Ps = "11"
(from just above) and Pt = "?"
, plugged into the OSC Ps ; Pt ST
. In the echo, \033
is being used for escape, and \\
for the final backslash.
echo -en "\033]11;?\033\\"
Output:
^[]11;rgb:0000/0000/0000^[\
Warning: The returned color does not reflect whether reverse video, like -rv
, is enabled, and crawling through the ~260 colors available via OSC 4 ; c ; ? ST
doesn't show any that both follow the background AND change with reverse video. Since many users set a dark background by using just xterm -rv
, this complicates determining whether the background is actually dark or not. Most colors don't adjust to -rv
, either.
A script to do the full query and actually capture the reply from xterm:
#!/bin/bash
success=false
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
col=11 # background
# OSC Ps ;Pt ST
echo -en "\033]${col};?\033\\" >/dev/tty # echo opts differ w/ OSes
result=
if IFS=';' read -r -d '\' color ; then
result=$(echo $color | sed 's/^.*\;//;s/[^rgb:0-9a-f/]//g')
success=true
fi
stty $oldstty
echo $result
$success
1Now this is pure terminal voodoo. Excellent answer. – Qix - MONICA WAS MISTREATED – 2014-10-31T05:48:58.790
Here is a program that makes this easy: https://github.com/JessThrysoee/xtermcontrol/tree/master/doc
– Tim Smith – 2018-06-13T02:27:30.5501Wow...a response after two years...thank you. I didn't quite understand the explanation but the example does nothing for me...echoes nothing. – Miserable Variable – 2012-03-29T17:08:17.943
Heh. I'm re-running it in a pretty recent xterm - an actual xterm - this time with all my X resources stripped out (which means it yields all "f"s for the colors instead of all "0"s). Using either /bin/echo or bash's builtin echo works fine. The example I tried was copy/pasted directly from the post above. My environment is Ubuntu 11.10 (a Linux/Debian derivative). I don't have a different OS handy to test. – Alex North-Keys – 2012-03-29T18:23:09.100
Depending on how your prompt is configured, there's a chance that it's landing on top of xterm's attempt to stuff input into your terminal in response to your query. From your shell's perspective, xterm's reply just looks like you, typing. – Alex North-Keys – 2012-03-29T18:45:39.023
Previously I had set
PS1
to\$>
when I did not see any output. Now I tried$> /bin/echo -en "\033]11;?\033\\" | od -cx
and exactly the same string on my terminal:0000000 033 ] 1 1 ; ? 033 \
– Miserable Variable – 2012-03-29T20:27:56.0101Hmm, gnome terminal in Ubuntu 12.04 claims to be xterm-compatible, but doesn't print anything back. Why is that? – Nik Reiman – 2012-09-21T13:03:26.703