如何检测当前终端是否支持 ANSI 真彩色(24-bit)

11次阅读

最可靠方式是检查$COLORTERM是否为truecolor或24bit;若未设置,需用tput setaf 16777215实测;勿单凭$TERM判断,应结合termenv或rich等库综合探测,并兼顾NO_COLOR和isatty。

如何检测当前终端是否支持 ANSI 真彩色(24-bit)

直接看 $COLORTERM 环境变量最省事

绝大多数现代终端(如 kitty、alacritty、windows Terminal、iTerm2 v3+、VS Code 终端)在启用真彩色时,会主动设置 COLORTERM=truecolorCOLORTERM=24bit。这是最轻量、最可靠的“捷径”判断方式。

  • python 中只需一行:os.getenv("COLORTERM") in ("truecolor", "24bit")
  • bash 中可直接:[[ $COLORTERM == "truecolor" || $COLORTERM == "24bit" ]]
  • 注意:该变量可能完全未设置(如某些 tmux 会话或旧版终端),此时不能反推“不支持”,只能说明没声明——需进一步试探

tput setaf 16777215 实锤验证是否真彩就绪

tput colors 只能告诉你最多支持多少色(256 或 0/8/16),但无法区分“256 色”和“真彩色”。真正能触发 RGB 渲染能力的,是尝试设置一个高位颜色码——16777215(即 0xFFFFFF,纯白真彩)。

  • 成功执行 tput setaf 16777215 且退出码为 0,基本可确认真彩色通道可用
  • 失败常见原因:终端本身不支持、terminfo 数据未更新(如 TERM=xterm 但实际是 alacritty)、或被中间层(如 tmux)拦截
  • Python 示例中务必加 timeout=0.3 和异常捕获,避免卡死或因无 tput 崩溃

别信 $TERM 单独判断,它只是个名字不是说明书

TERM=xterm-256color 表示“声称支持 256 色”,但不等于支持真彩色;TERM=screen 可能被 tmux 包裹后降级;TERM=linux 几乎肯定不支持。单看 $TERM 容易误判。

  • 它本质是 terminfo 数据库的索引键,真实能力取决于系统安装的 terminfo 条目 + 终端实际实现
  • 例如 macOS 默认 TERM=apple-terminal,但真彩支持依赖 iTerm2 版本或 Terminal.app 设置,与 $TERM 无关
  • 安全做法:把 $TERM 当作辅助线索,不作为决策依据

termenv.Profile()rich.console.get_console().color_system 省去手写逻辑

手动拼接环境变量 + tput 调用容易漏 case(比如 windowstput 不可用、WSL 中 $COLORTERM 为空但实际支持)。成熟库已封装这些边界:

  • termenvgo/Python)自动按优先级查 $COLORTERMtput$TERM → 默认降级,返回 TrueColor/ANSI256 等枚举值
  • richConsole(color_system="auto") 启动时就做完整探测,console.color_system 属性可直接读取结果
  • 如果你在写 CLI 工具,直接依赖这类库比自己 roll 更稳——毕竟连 VS Code 终端的 quirks 都已被收录进它们的检测逻辑里

真彩色检测真正的复杂点不在“怎么查”,而在“查完之后要不要用”:即使终端支持,用户也可能禁用(如设了 NO_COLOR=1),或当前输出重定向到文件(sys.stdout.isatty() == False)。所以最终渲染前,还得叠加这两层判断。

text=ZqhQzanResources