Unix 如何确定终端是否支持颜色?

Unix 如何确定终端是否支持颜色?,unix,terminal,termcap,terminfo,Unix,Terminal,Termcap,Terminfo,我想更改一个程序来自动检测终端是否支持颜色,因此当我从一个不支持颜色的终端(比如(x)Emacs中的M-x外壳)中运行该程序时,颜色会自动关闭 我不想硬编码程序来检测TERM={emacs,dumb} 我认为termcap/terminfo应该能够帮助解决这个问题,但到目前为止,我只使用一段代码拼凑出了这个(n)诅咒,当它找不到终端时,它会严重失败: #include <stdlib.h> #include <curses.h> int main(void) { in

我想更改一个程序来自动检测终端是否支持颜色,因此当我从一个不支持颜色的终端(比如(x)Emacs中的M-x外壳)中运行该程序时,颜色会自动关闭

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

我认为termcap/terminfo应该能够帮助解决这个问题,但到目前为止,我只使用一段代码拼凑出了这个(n)诅咒,当它找不到终端时,它会严重失败:

#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);
}

这是。。。次优。

一位朋友向我指出了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 "$@"

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

查找terminfo(5)条目中的终端类型,并检查Co(最大颜色)条目。这就是终端支持的颜色。

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

#包括
#包括
内部主(空){
char*term=getenv(“术语”);
int-erret=0;
if(setupterm(NULL、1和erret)==ERR){
char*errmsg=“未知错误”;
开关(erret){
案例1:errmsg=“终端为硬拷贝,不能用于诅咒应用程序”中断;
案例0:errmsg=“找不到终端,或者没有足够的信息用于诅咒应用程序”中断;
案例1:errmsg=“无法找到terminfo条目”中断;
}
printf(“对终端\%s\”的颜色支持未知(错误%d:%s)。\n”,term,erret,errmsg);
出口(1);
}
bool colors=有颜色();
printf(“终端\%s\%s颜色。\n”,术语,颜色?“有”:“没有”);
返回0;
}

有关使用
setupterm
的更多信息,请参阅curs_terminfo(3X)手册页(x-man-page://3x/curs_terminfo)而且。

归根结底,你不能,因为你不能说出终端是用什么样的CRT实现的。我感兴趣的是终端(类型)表示它是否具有颜色功能-不是在对CRT发出的光谱进行分析时:-)请注意,ncurses的
具有颜色()
比只检查颜色的数量执行更全面的测试,因为这不是用terminfo表示颜色支持的唯一方法。但是。。。但是
tput
手册没有提到“颜色”命令。你的朋友是怎么发现这个漂亮的功能的??!tput(1)手册页显示“tput[-Ttype]capname[parameters]”,因此“colors”是一个“capname”,是terminfo数据库中定义的功能,而不是命令。所以我想看看TeNFO(5),了解一下有哪些能力。在C++中,我的Mac OSX机也需要包含。
#!/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 "$@"
#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;
}