Как определить, поддерживает ли терминал цвет?
Я хотел бы изменить программу, чтобы автоматически определять, поддерживает ли терминал цвет, или нет, поэтому, когда я запускаю указанную программу из терминала, не поддерживающего цвета (скажем, Mx shell в (X)Emacs), цвет автоматически отключается.,
Я не хочу жестко кодировать программу, чтобы обнаружить TERM={emacs, тупой}.
Я думаю, что 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 ответа
Друг указал мне на 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.
У вас почти это было, за исключением того, что вам нужно использовать функцию 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;
}
Дополнительная информация об использовании setupterm
доступно на справочной странице curs_terminfo(3X) (x-man-page://3x/curs_terminfo) и написание программ с помощью NCURSES.
Найдите запись terminfo(5) для типа терминала и проверьте запись Co (max_colors). Вот сколько цветов поддерживает терминал.