【问题标题】:How do I determine if a terminal is color-capable?如何确定终端是否具有颜色功能?
【发布时间】:2011-01-28 18:07:55
【问题描述】:

我想更改一个程序以自动检测终端是否具有颜色功能,因此当我从不支持颜色的终端(例如 (X)Emacs 中的 Mx shell)中运行所述程序时,颜色是自动关闭。

我不想硬编码程序来检测 TERM={emacs,dumb}。

我认为 termcap/terminfo 应该能够帮助解决这个问题,但到目前为止,我只设法拼凑了这个 (n)curses-using sn-p of code,当它不能时,它会严重失败找到终端:

#include <stdlib.h>
#include <curses.h>

int main(void) {
 int colors=0;

 initscr();
 start_color();
 colors=has_colors() ? 1 : 0;
 endwin();

 printf(colors ? "YES\n" : "NO\n");

 exit(0);
}

即我明白了:

$ gcc -Wall -lncurses -o hep hep.c
$ echo $TERM
xterm
$ ./hep
YES
$ export TERM=dumb
$ ./hep           
NO
$ export TERM=emacs
$ ./hep            
Error opening terminal: emacs.
$ 

这是……次优的。

【问题讨论】:

  • 说到底你不能,因为你不知道终端是用什么样的CRT实现的。
  • 我对终端(类型)是否说它具有颜色能力感兴趣 - 不是对从 CRT 发出的光的光谱进行分析 :-)

标签: unix terminal termcap terminfo


【解决方案1】:

一位朋友向我介绍了 tput(1),我提出了这个解决方案:

#!/bin/sh

# ack-wrapper - use tput to try and detect whether the terminal is
#               color-capable, and call ack-grep accordingly.

OPTION='--nocolor'

COLORS=$(tput colors 2> /dev/null)
if [ $? = 0 ] && [ $COLORS -gt 2 ]; then
    OPTION=''
fi

exec ack-grep $OPTION "$@"

这对我有用。不过,如果我有办法将其集成到 ack 中,那就太好了。

【讨论】:

  • 请注意,ncurses 的 has_colors() 执行的测试比仅检查颜色数量更全面,因为这不是在 terminfo 中表达颜色支持的唯一方式。
  • 但是...但是...tput 手册没有提到“颜色”命令。你的朋友是怎么知道这个漂亮的功能的??!
  • tput(1) 手册页显示“tput [-Ttype] capname [parameters]”,因此“colors”是“capname”,是在 terminfo 数据库中定义的功能,而不是命令。所以我想看看 terminfo(5) 了解有哪些功能。
【解决方案2】:

您几乎拥有它,除了您需要使用较低级别的curses函数setupterm而不是initscrsetupterm 只是执行足够的初始化来读取 terminfo 数据,如果你传入一个指向错误结果值的指针(最后一个参数),它将返回一个错误值而不是发出错误消息并退出(initscr 的默认行为)。

#include <stdlib.h>
#include <curses.h>

int main(void) {
  char *term = getenv("TERM");

  int erret = 0;
  if (setupterm(NULL, 1, &erret) == ERR) {
    char *errmsg = "unknown error";
    switch (erret) {
    case 1: errmsg = "terminal is hardcopy, cannot be used for curses applications"; break;
    case 0: errmsg = "terminal could not be found, or not enough information for curses applications"; break;
    case -1: errmsg = "terminfo entry could not be found"; break;
    }
    printf("Color support for terminal \"%s\" unknown (error %d: %s).\n", term, erret, errmsg);
    exit(1);
  }

  bool colors = has_colors();

  printf("Terminal \"%s\" %s colors.\n", term, colors ? "has" : "does not have");

  return 0;
}

有关使用 setupterm 的其他信息,请参阅 curs_terminfo(3X) 手册页 (x-man-page://3x/curs_terminfo) 和 Writing Programs with NCURSES

【讨论】:

  • 在我的 Mac OSX 机器上的 C++ 中,我还需要#include
  • > 终端是硬拷贝,不能用于curses应用程序 我想知道是否有类似日志的终端,既不能擦除任何东西,也不能移动光标,但仍然支持颜色并且在某种程度上有用用ncurses?例如。许多 CI 环境都这样做。
【解决方案3】:

查找终端类型的 terminfo(5) 条目并检查 Co (max_colors) 条目。这就是终端支持的颜色数量。

【讨论】:

    猜你喜欢
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多