如何从 `\e]11;?\a` 获取人类可读的(例如 RGB)值?

如何从 `\e]11;?\a` 获取人类可读的(例如 RGB)值?

该字符串\e]11;?\a可能会产生当前终端的背景颜色,但我还没有找到一种方法来使用此信息来获取人类可读(例如 RGB)格式的颜色。

我确实尝试过(无能为力)

print -P '\e]11;?\a'

但它什么也没有产生,或者至少没有产生任何可见的东西。

顺便说一句,我知道xtermcontrol --get-bg,但是当我在我正在使用的终端上运行它时,我收到错误:

xtermcontrol: --get-bg is unsupported or disallowed by this terminal. \
See also, TROUBLESHOOTING section of xtermcontrol(1) manpage.

(所提到的TROUBLESHOOTING section没有提供任何解决方法。)

顺便说一句,我故意省略了有关我正在使用的终端的详细信息,因为我希望找到一种通用的解决方案,而不是仅适用于特定终端的解决方案。

答案1

这个问题有几个基本问​​题:

  1. 为了产生通用解决方案,该命令必须得到以下支持ANSI X3.64,基本标准为所有现代航站楼,但据我所知,这不是 ANSI 命令。

    我不确定,因为我没有该标准的副本,我在网上找不到,而且 ANSI 也不会卖给我一个。我在网上能找到的都是混蛋的“参考资料”。正如我所描述的别处,虽然 X3.64 是所有常见现代终端的根标准,但这种观察有点像指出狗是狼的后代:通过研究狼来了解狗会严重限制你可以学习的东西的范围。

    我发现的最好的资源是XTerm 控制序列参考,由当前xterm维护者维护。但是,这不是一个规范标准,它只是描述一个通用程序的功能。许多程序都源自xterm源代码,但就像狗与狼一样,许多程序存在显着差异。

    我怀疑如果你追查的话你会发现这个命令是由xterm作为 ANSI X3.64 的扩展,而您的目标终端不支持该特定xterm扩展,这就是xtermcontrol失败的原因。

  2. 即使您的特定终端集都对此命令做出答复,我也看不到上述参考文件您将获得 RGB 值。您很可能会得到一个颜色名称。

    (这是我们期望规范性标准确定的细节,但在功能描述文档中经常被忽视。)

    另外,请注意,即使您确实收到了 R;G;B 回复,答案也可能会有所不同。如果您使用旧的 ANSI X3.64 颜色代码设置颜色,则没有标准说明它们映射到哪种 RGB 颜色;事实上,xterm我用过的每个家庭终端程序都提供了一种方法来更改用于 ANSI 颜色代码的 RGB 颜色。此外,您可以在某些终端程序中动态更改这些值,以便由第三方程序运行分开运行的两个程序可能会给出不同的答案,因为现在的颜色方案不同。

另一个答案在 SE 网络中,它执行与您的print语句大致相同的操作,但与您的命令一样,另一个答案的echo命令不会从 OS X 的终端获得任何响应,该终端声称是xterm-256color终端。这意味着该解决方案甚至不适用于所有 xterm 系列终端。

我编写了一个更强大的 C 程序,如果发生错误,它会诊断错误,如果没有发生,则以可打印的形式显示返回值。您可能会发现它比 shell 命令更适合扩展:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char reply[40];
size_t nr;

void timeout(int sn)
{
    if (nr > 0) {
        for (size_t i = 0; i < nr; ++i) {
            printf("Got char %d\n", reply[i]);
        }

        if (!sn) puts("WARNING: Buffer filled!");
    }
    else {
        puts("No reply from terminal.");
    }

    exit(0);
}

int main(void)
{
    signal(SIGALRM, timeout);
    alarm(1);
    printf("\e]11;?\a");

    for (nr = 0; nr < sizeof(reply); ++nr) {
        reply[nr] = getchar();
    }

    timeout(0);   /* buffer filled before alarm() timer went off! */
    return 0;
}

答案2

首先,某些替代方法(除了对控制序列的响应之外)不太可能成为OP所请求的“通用解决方案”的基础,因为所寻求的属性不(例如)适用于使用窗口属性的方法。

接下来,这是在 xterm 中实现但不普遍可用的控制序列的示例。开发商为xtermcontrol意识到这一点。他的页面讨论了xterm控制序列,评论说它们有很多(a过多),并提到 OSX终端程序支持一些其中。

OP报告的错误信息当然足够清楚了。 OP 尝试运行的未命名程序xtermcontrol不支持该功能。很可能,它不支持可以替代使用的类似功能。

实际上,大多数 xterm 的控制序列并未在其他终端中实现,无论其开发人员如何使用“xterm”作为终端描述。例如,请参阅 xterm 常见问题解答通过计数控件来比较版本,以及 ncurses 常见问题解答为什么不直接使用 TERM 设置为“xterm”?(请注意,“从xterm源代码派生”可以用不止一种方式解释)。

OP(可能)更感兴趣的终端没有关于它们实现的控制序列的有用文档。因此,了解您所拥有的解决方案有多“通用”的唯一方法就是对其进行详尽的测试。这似乎不是很普遍。

投票最高的超级用户答案是 所使用的方法xtermcontrol。 (这被否决的xrdb答案不会给你当前的颜色设置xterm,只有它的初始值 - 也许甚至不是。)

相关内容