答案1
这个来源说检查是否$COLORTERM
包含24bit
或truecolor
。
sh
[ "$COLORTERM" = truecolor ] || [ "$COLORTERM" = 24bit ]
bash
/ zsh
:
[[ $COLORTERM =~ ^(truecolor|24bit)$ ]]
答案2
只需使用tput colors
.我相信测试终端能力$TERM
是比解析或您自己更安全的测试$COLORTERM
。
if (( $(tput colors 2>/dev/null) > 256 )); then
echo "What a beautiful rainbow!!!"
else
echo "Back to the 80's VGA era anyone?"
fi
当然,tput
只输出做广告的中注册的功能术语信息数据库,所以它可能无法准确反映您的实际的终端能力。
不幸的是,根据评论,许多终端仍然有错误或过时的信息,特别是在 Windows 和 MacOS 等平台上。希望,只要有足够的时间(和错误报告!),此类终端最终将进行$TERM
适当的设置。毕竟,Terminfo 数据库支持 24 位颜色已有 4 年了。
答案3
我已经从我的程序中删除了这个 C++ 解决方案。
首先,设置 termios,以便您一次可以读取一个字符......
#include <termios.h>
struct termios tio, tio_init;
tcgetattr(0, &tio_init); // Keep a copy so you can reset later
tcgetattr(0, &tio);
tio.c_iflag &= ~(IXON | IXOFF); // Pass Ctrl-S and Ctrl-Q
tio.c_lflag &= ~(ECHO | ICANON);
tio.c_cc[VSUSP] = 0; // Pass Ctrl-Z (confuses terminal)
tio.c_cc[VMIN] = 0;
tio.c_cc[VTIME] = 1;
tcsetattr(0, TCSANOW, &tio);
下面是一个简单的例程,它提交 ANSI 查询,并从回复中提取字符。我们假设终端程序速度很快,并且 1 个刻度(0.1 秒)术语字符超时将告诉我们回复字符何时停止出现。有时需要终止'\n'来让终端程序执行命令。它可能会一直徘徊,直到它决定需要重新绘制为止。
void AnsiViewQuery(char *reply, const char *query, int size) {
printf("%s\n", query);
int len = 0;
while (len < size-1) {
if (read(0, reply+len, 1) == 1) ++len;
else break;
}
reply[len] = '\0';
}
我们将前景色设置为1;2;3,然后看看是否可以再次读取它......
char reply[32];
printf("\e[38;2;1;2;3m");
AnsiViewQuery(reply, "\eP$qm\e\\", 32);
int truecolor = strncmp("\eP1$r0;38:2::1:2:3m", reply, 19) ? 0 : 1;
这并不是万无一失的。我想设置 24 位颜色,但不需要读回它们。如果写作和阅读都有效,则该测试通过。某些终端(例如 Gnome 终端)支持其中一种,但不支持另一种。如果它认为支持真彩色,那就应该是对的。也许你可以改进这一点。
同一程序输出一个 unicode 字符并检查光标是否移动了一个字符,以检查是否支持特定的 unicode 集。