【问题标题】:How to determine a terminal's background color?如何确定终端的背景颜色?
【发布时间】:2020-09-03 15:25:04
【问题描述】:

我想知道是否有任何方法可以确定终端的背景颜色?

就我而言,使用 gnome-terminal。
这可能很重要,因为它完全取决于终端应用程序来绘制其窗口的背景,甚至可能不是纯色。

【问题讨论】:

    标签: unix terminal x11 gnome-terminal


    【解决方案1】:

    这里有一个xterm control sequence

    \e]11;?\a
    

    \e\a 分别是 ESC 和 BEL 字符。)

    Xterm 兼容的终端应该以相同的顺序回复,问号替换为X11 color name,例如rgb:0000/0000/0000 代表黑色。

    【讨论】:

    • 一些关于如何使用它的信息将是一个很好的补充。 (例如,shell 脚本的 sn-p 会根据 shell 的背景颜色以不同的前景色打印单词?)
    • (另外,我怀疑这只会获得文本的背景颜色,如果关闭的话。不是我怀疑的实际终端窗口的背景颜色在rxvt之外仍然无法获得。)
    • 在 Mac 10.10.4 中,这个(和@blueyed 的类似答案)似乎在 Apple 终端(将自身标识为 xterm-color)中不起作用,但在常规 xterm 中起作用。跨度>
    • 在我的系统 (Ubuntu 15.10) 上,这适用于 xterm 和 GNOME 终端 3.16.2,但不适用于 MATE 终端 1.10.1。
    • 确认此解决方案在 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 语句中使用它。这可能吗?
    【解决方案2】:

    我想出了以下几点:

    #!/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/]\+$//'
    

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

    【讨论】:

    • 这似乎不适用于 gnome-terminal 3.6.2。
    • 在 gnome-terminal 3.36.1 下工作,但睡眠时间需要更长,例如sleep 0.01
    • 开头还有一个转义序列,所以我用sed 's/.*\(rgb:[0-9a-f/]*\).*/\1/'过滤了
    • @blueyed,有没有如何用 ANSI RGB 颜色替换 XTERM RGB 颜色?
    【解决方案3】:

    一些链接:

    例如来自Neovim issue 2764的一些相关sn-p:

    /*
     * 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";
    }
    

    关于COLORFGBG env,来自Gnome BugZilla 733423

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

    这是我正在使用的一些自己的代码 (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)
    

    【讨论】:

    • 特别感谢关于 $COLORFGBG 的提示。它至少适用于 iTerm2。获取 iTerm2 会话背景颜色的非常直接的方法。 +1
    【解决方案4】:

    除了apparently rxvt-only $COLORFGBG,我不知道还有其他东西存在。大多数人似乎是referring tovim does it,即使这充其量只是一个有根据的猜测。

    【讨论】:

      【解决方案5】:

      您的意思是确定终端背景颜色或设置终端颜色的方法吗?

      如果是后者,您可以查询终端的 PS1 环境变量以获取颜色。

      这里有一篇关于设置(以及派生)终端颜色的文章: http://www.ibm.com/developerworks/linux/library/l-tip-prompt/

      【讨论】:

      • 我的意思是确定背景颜色。不是用于打印字符的颜色(使用转义码),而是窗口本身的颜色。不过文章不错:)
      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2012-02-11
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 2011-06-11
      相关资源
      最近更新 更多