asj*_*sjo 28 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);
}
Run Code Online (Sandbox Code Playgroud)
即我明白了:
$ 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.
$
Run Code Online (Sandbox Code Playgroud)
这是......次优的.
asj*_*sjo 21
一位朋友向我指出了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 "$@"
Run Code Online (Sandbox Code Playgroud)
这适合我.不过,如果我有办法将它整合到ack中会很棒.
你几乎拥有它,除了你需要使用较低级别的curses函数setupterm而不是initscr.setupterm只执行足够的初始化来读取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;
}
Run Code Online (Sandbox Code Playgroud)
有关使用的更多信息,setupterm请参见curs_terminfo(3X)手册页(x-man-page:// 3x/curs_terminfo)和使用NCURSES编写程序.