有没有办法确定终端的背景颜色?

Rom*_*net 16 unix x11 terminal gnome-terminal

(不确定这个问题是属于这里还是属于超级用户)

我想知道是否有办法确定终端的背景颜色?

在我的情况下,使用gnome-terminal.
它可能很重要,因为它完全由终端应用程序绘制窗口的背景,甚至可能是纯色的东西.

ak2*_*ak2 13

这有一个xterm控制序列:

\e]11;?\a
Run Code Online (Sandbox Code Playgroud)

(\e\a是ESC和BEL字符,分别).

Xterm兼容终端应以相同的顺序回复,问号由X11 colorspec替换,例如rgb:0000/0000/0000黑色.

  • 关于如何利用这一点的一些信息将是一个很好的补充.(例如,一个shell脚本片段,根据shell的背景颜色打印不同前景色的单词?) (4认同)
  • 确认此解决方案在 iTerm2 和终端中均适用于 Mac OS-X BigSur: `❯ printf "\e]11;?\a"` 会生成 `^[]11;rgb:0000/0000/0000^G%` 和在 iTerm2 中: `❯ printf "\e]11;?\a"` 产生 `^[]11;rgb:0000/0000/0000^G` 但是,我无法捕获此输出并将其用于shell 脚本中的 if 语句。那可能吗? (4认同)
  • 在Mac 10.10.4中,这个(和@blueyed的类似答案)在Apple终端中似乎不起作用(它将自己标识为xterm-color),但在常规xterm中有效. (3认同)

blu*_*yed 6

我想出了以下内容:

#!/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/]\+$//'
Run Code Online (Sandbox Code Playgroud)

来源/回购/要点:https://gist.github.com/blueyed/c8470c2aad3381c33ea3


Alb*_*ert 5

一些链接:

例如,来自Neovim 问题 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";
}
Run Code Online (Sandbox Code Playgroud)

关于COLORFGBGenv,来自Gnome BugZilla 733423

在我刚刚在 linux 上尝试过的很多终端中,只有 urxvt 和 konsole 设置了它(那些没有设置:xterm、st、terminology、pterm)。Konsole 和 Urxvt 使用不同的语法和语义,即对我来说,konsole 将其设置为“0;15”(即使我使用“浅黄色黑色”配色方案 - 那么为什么不使用“默认”而不是“15”呢?),而我的 urxvt 将其设置为“0;default;15”(它实际上是白底黑字 - 但为什么是三个字段?)。因此,这两个值都不符合您的规范。

这是我正在使用的一些自己的代码(通过):

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 </sf/ask/175513621/>`__.
        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)
Run Code Online (Sandbox Code Playgroud)