![如何从 `\e]11;?\a` 获取人类可读的(例如 RGB)值?](https://linux22.com/image/77027/%E5%A6%82%E4%BD%95%E4%BB%8E%20%60%5Ce%5D11%3B%3F%5Ca%60%20%E8%8E%B7%E5%8F%96%E4%BA%BA%E7%B1%BB%E5%8F%AF%E8%AF%BB%E7%9A%84%EF%BC%88%E4%BE%8B%E5%A6%82%20RGB%EF%BC%89%E5%80%BC%EF%BC%9F.png)
该字符串\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
这个问题有几个基本问题:
为了产生通用解决方案,该命令必须得到以下支持ANSI X3.64,基本标准为所有现代航站楼,但据我所知,这不是 ANSI 命令。
我不确定,因为我没有该标准的副本,我在网上找不到,而且 ANSI 也不会卖给我一个。我在网上能找到的都是混蛋的“参考资料”。正如我所描述的别处,虽然 X3.64 是所有常见现代终端的根标准,但这种观察有点像指出狗是狼的后代:通过研究狼来了解狗会严重限制你可以学习的东西的范围。
我发现的最好的资源是XTerm 控制序列参考,由当前
xterm
维护者维护。但是,这不是一个规范标准,它只是描述一个通用程序的功能。许多程序都源自xterm
源代码,但就像狗与狼一样,许多程序存在显着差异。我怀疑如果你追查的话你会发现这个命令是由xterm作为 ANSI X3.64 的扩展,而您的目标终端不支持该特定
xterm
扩展,这就是xtermcontrol
失败的原因。即使您的特定终端集都对此命令做出答复,我也看不到上述参考文件您将获得 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
,只有它的初始值 - 也许甚至不是。)