Как определить, поддерживает ли терминал цвет? - PullRequest
27 голосов
/ 17 марта 2010

Я хотел бы изменить программу, чтобы автоматически определять, поддерживает ли терминал цвет, или нет, поэтому, когда я запускаю указанную программу из терминала, не поддерживающего цвета (скажем, Mx shell в (X) Emacs), цвет автоматически отключается.

Я не хочу жестко задавать программу для обнаружения 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 ]

20 голосов
/ 17 марта 2010

Друг указал мне на 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 .

9 голосов
/ 15 сентября 2011

У вас почти было это, за исключением того, что вам нужно использовать функцию проклятий нижнего уровня 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 .

3 голосов
/ 18 марта 2010

Найдите запись terminfo (5) для типа терминала и проверьте запись Co (max_colors). Вот сколько цветов поддерживает терминал.

...