Как проверить, может ли bash печатать цвета

62

Я хочу знать, есть ли способ проверить, может ли моя программа выводить вывод терминала, используя цвета или нет.

При выполнении команд, например, lessи просмотре вывода из программы, которая выводит с использованием цветов, вывод отображается неправильно, как

[ESC[0;32m0.052ESC[0m ESC[1;32m2,816.00 kbESC[0m]

Спасибо

Анджело Варгас
источник

Ответы:

68

Идея состоит в том, чтобы мое приложение знало, что не нужно раскрашивать вывод, если программа не может напечатать, скажем, запись в журнал выходных данных с помощью задания cron в файл, нет необходимости регистрировать цветной вывод, но при запуске вручную, мне нравится просматривать цветной вывод

На каком языке вы пишете свое заявление?

Обычный подход состоит в том, чтобы проверить, является ли устройство вывода tty, и если это так, проверьте, поддерживает ли этот тип терминала цвета.

Во bash, это будет выглядеть

# check if stdout is a terminal...
if test -t 1; then

    # see if it supports colors...
    ncolors=$(tput colors)

    if test -n "$ncolors" && test $ncolors -ge 8; then
        bold="$(tput bold)"
        underline="$(tput smul)"
        standout="$(tput smso)"
        normal="$(tput sgr0)"
        black="$(tput setaf 0)"
        red="$(tput setaf 1)"
        green="$(tput setaf 2)"
        yellow="$(tput setaf 3)"
        blue="$(tput setaf 4)"
        magenta="$(tput setaf 5)"
        cyan="$(tput setaf 6)"
        white="$(tput setaf 7)"
    fi
fi

echo "${red}error${normal}"
echo "${green}success${normal}"

echo "${green}0.052${normal} ${bold}${green}2,816.00 kb${normal}"
# etc.

В C вам нужно гораздо больше печатать, но вы можете добиться того же результата, используя isatty и функции, перечисленные в man 3 terminfo.

Mikel
источник
^^ это ^^ было именно то , что я искал. Благодарю.
Тим Кеннеди
Спасибо за подсказку о tput. Это действительно отличный ответ.
AmadeusDrZaius
24

Этого должно быть достаточно:

$ tput colors

Цвета tput объяснили:

Если вы посмотрите на страницу руководства, вы заметите это:

SYNOPSIS
       tput [-Ttype] capname [parms ... ]

А также...

   capname
          indicates the capability from the terminfo database.  When term
          cap  support is compiled in, the termcap name for the capability
          is also accepted.

Termcap colorsнаходится в базе данных terminfo, поэтому вы можете запросить его. Если у вас нулевой статус выхода, то termcap компилируется. Но если у вас есть что-то вроде:

$ tput unknowntermcap
tput: unknown terminfo capability 'unknowntermcap'
$ echo $?
4

Это показывает, что unknowntermcap не существует. Итак, это:

$ tput colors
8
$ echo $?
0

Показывает, что ваша команда была права.

Другие полезные способы:

  • В C вы можете просто использовать isatty и посмотреть, является ли это TTY
  • Посмотрите, является ли это тупой терминал, выглядящий переменной $ TERM

ура

D4RIO
источник
colorsне задокументировано в tputсправочной странице (!), поэтому я должен искать число> = 8 в stdout или код возврата 0?
10
Кажется очевидным, но ваш комментарий показывает, что это не так. Я добавляю эту информацию (кратко, цвета - это возможность базы данных terminfo)
D4RIO
1
colorsВозможность документирована в terminfo В (5) . Тестирование с использованием tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorsпредполагает общие ценности не являются -1(без цвета поддержки) и 8(8 цветов). Обратите внимание, что это применимо только после проверки выходного устройства терминала (например, [ -t 1 ]или isatty).
Микель
Обратите внимание, что tput colorsвозвращает то, что локальная база данных терминала думает о терминале. Это может или не может соответствовать тому, что на самом деле может делать терминал, особенно для типа терминала, xtermкоторый существует во многих вариантах (в диапазоне от черного и белого до 256 цветов).
Жиль "ТАК - перестань быть злым"
7

Идея состоит в том, чтобы мое приложение знало, что не нужно раскрашивать вывод, если программа не может напечатать, скажем, протоколирование вывода из задания cron в файл, нет необходимости записывать цветной вывод, но при запуске вручную, мне нравится просматривать вывод цветной.

Для этого случая использования то, что обычно делают программы (например, GNU ls или GNU grep with --color=auto), - это использование цветов, если их вывод идет на терминал, и никаких цветов в противном случае. Терминалы, которые не поддерживают последовательности изменения цвета ANSI, достаточно редки, чтобы их пользователи могли переопределить выбор по умолчанию. В любом случае, убедитесь, что в вашем приложении есть возможность включать или выключать цвета.

В сценарии оболочки используйте [ -t 1 ]для проверки, является ли стандартный вывод терминалом.

# option processing has set $color to yes, no or auto
if [ $color = auto ]; then
  if [ -t 1 ]; then color=yes; else color=no; fi
fi

Из программы, использующей C API, позвоните isatty(1).

# option processing has set use_color to 0 for no, 1 for yes or 2 for auto
if (use_color == 2) use_color = isatty(1);
Жиль "ТАК - перестань быть злым"
источник
5

Выполнение таких команд, как поменьше и просмотр выходных данных из программы, которая выводит с использованием цветов, вывод отображается неправильно, например

[ESC [0; 32m0,052ESC [0m ESC [1; 32m2 816,00 кБЕС [0m])

Попробуйте использовать less --RAW-CONTROL-CHARS.

В этом примере я использую logtool , который печатает вывод, используя цвета.

Без --RAW-CONTROL-CHARS:

$ head -20 /var/log/messages | logtool | less
ESC[0mESC[0;37mMar 20 11:43:52ESC[0mESC[1;36m host1ESC[0mESC[0;37m rsyslogd:ESC[0m ^GESC[0;31mlast message repeated 14 timesESC[0mESC[0m

С --RAW-CONTROL-CHAR (Представьте, что это в красивых цветах. Кроме того, я не уверен, почему это ^Gотображается.):

$ head -20 /var/log/messages | logtool | less --RAW-CONTROL-CHARS
Mar 20 11:43:52 host1 rsyslogd: ^Glast message repeated 14 times
Стефан Ласевский
источник
2

Это было бы ошибкой того, что lessне настроено интерпретировать побеги ANSI; искать Rв $LESSOPTS. Что касается определения, знает ли система, что ваш терминал может работать с цветами, tput colorsвыведет либо количество цветов, которые она поддерживает, либо -1он не поддерживает цвета. (Обратите внимание, что некоторые терминалы могут использовать xtermвместо xterm-colorописания своих терминалов, но все еще поддерживают цвета.)

geekosaur
источник
Идея состоит в том, чтобы мое приложение знало, что не нужно раскрашивать вывод, если программа не может напечатать, скажем, запись в журнал выходных данных с помощью задания cron в файл, нет необходимости регистрировать цветной вывод, но при запуске вручную, мне нравится просматривать вывод цветной.
Анджело Варгас