如何确定终端是否具有颜色功能?

时间:2010-03-17 19:59:02

标签: unix terminal termcap terminfo

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

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

我认为termcap / terminfo应该能够帮助解决这个问题,但到目前为止,我只是设法将这个(n)curses - 使用代码片段拼凑在一起,当它无法找到时,它会严重失败终端:

#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.
$ 

这是......次优。

3 个答案:

答案 0 :(得分:20)

一位朋友向我指出了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中,那将会很棒。

答案 1 :(得分:9)

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

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; } 的更多信息,请参见curs_terminfo(3X)手册页(x-man-page:// 3x / curs_terminfo)和Writing Programs with NCURSES

答案 2 :(得分:3)

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