Jak sprawdzić, czy bash może drukować kolory

62

Chcę wiedzieć, czy jest jakiś sposób, aby sprawdzić, czy mój program może wyprowadzać dane wyjściowe terminala przy użyciu kolorów, czy nie.

Uruchamianie poleceń takich jak lessi patrząc na dane wyjściowe z programu, który wyświetla za pomocą kolorów, dane wyjściowe są wyświetlane nieprawidłowo, jak

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

Dzięki

Angelo Vargas
źródło

Odpowiedzi:

68

Chodzi o to, aby moja aplikacja wiedziała, że ​​nie należy pokolorować danych wyjściowych, jeśli program nie może wydrukować, powiedzmy, rejestrowania danych wyjściowych z zadania cron do pliku, nie trzeba rejestrować kolorowych danych wyjściowych, ale gdy uruchamiam ręcznie, lubię przeglądać wyjście kolorowe

W jakim języku piszesz swoją aplikację?

Normalnym podejściem jest sprawdzenie, czy urządzeniem wyjściowym jest tty, a jeśli tak, sprawdź, czy ten typ terminala obsługuje kolory.

Tak bashwyglądałoby

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

W C musisz dużo pisać, ale możesz osiągnąć ten sam wynik, używając isatty i funkcji wymienionych w man 3 terminfo.

Mikel
źródło
^^ że ^^ było dokładnie tym , czego szukałem. Dzięki.
Tim Kennedy,
Dzięki za podpowiedź na temat tput. To naprawdę świetna odpowiedź.
AmadeusDrZaius
24

To powinno wystarczyć:

$ tput colors

wyjaśniono kolory tput:

Jeśli spojrzysz na stronę podręczną, zauważysz to:

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

I...

   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 colorsznajduje się w bazie danych terminfo, więc możesz o to poprosić. Jeśli masz zerowy status wyjścia, kompilowana jest termcap. Ale jeśli masz coś takiego:

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

To pokazuje, że nieznany limit nie istnieje. Więc to:

$ tput colors
8
$ echo $?
0

Pokazuje, że twoje polecenie było słuszne.

Inne przydatne sposoby:

  • W C możesz po prostu użyć isatty i sprawdzić, czy jest to TTY
  • Sprawdź, czy jest to głupi terminal wyglądający na zmienną $ TERM

Twoje zdrowie

D4RIO
źródło
colorsnie jest udokumentowany na tputstronie podręcznika (!), więc czy powinienem szukać liczby> = 8 w stdout czy kodu powrotu 0?
l0b0
Wydawało się to oczywiste, ale twój komentarz pokazuje, że tak nie jest.
Dodam
1
colorsFunkcja jest opisana w terminfo (5) . Testowanie za pomocą tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorssugeruje wspólne wartości -1(bez obsługi kolorów) i 8(8 kolorów). Należy pamiętać, że dotyczy to tylko sprawdzenia, czy urządzeniem wyjściowym jest terminal (np. [ -t 1 ]Lub isatty).
Mikel
Zauważ, że tput colorszwraca to, co lokalna baza danych terminali myśli o terminalu. To może, ale nie musi odpowiadać temu, co terminal może faktycznie zrobić, zwłaszcza w przypadku takiego typu terminala, xtermktóry występuje w wielu wariantach (od czerni i bieli do 256 kolorów).
Gilles
7

Chodzi o to, aby moja aplikacja wiedziała, że ​​nie należy pokolorować danych wyjściowych, jeśli program nie może wydrukować, powiedzmy, rejestrowania danych wyjściowych z zadania cron do pliku, nie trzeba rejestrować kolorowych danych wyjściowych, ale gdy uruchamiam ręcznie, lubię przeglądać wyjście kolorowe.

W tym przypadku użycia programy zwykle wykonują (np. GNU ls lub GNU grep with --color=auto) używanie kolorów, jeśli ich dane wyjściowe trafiają do terminala, a w przeciwnym razie żadnych kolorów. Terminale, które nie obsługują sekwencji zmieniających kolory ANSI, są na tyle rzadkie, że dopuszczalne jest, aby ich użytkownicy zastąpili domyślny wybór. W każdym razie upewnij się, że aplikacja ma opcję wymuszania włączenia lub wyłączenia kolorów.

W skrypcie powłoki użyj, [ -t 1 ]aby sprawdzić, czy standardowym wyjściem jest terminal.

# 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

Z programu korzystającego z C API, wywołaj 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);
Gilles
źródło
5

Uruchamianie poleceń jak mniej i patrząc na dane wyjściowe z programu, który wyświetla za pomocą kolorów, dane wyjściowe są wyświetlane niepoprawnie, jak

[ESC [0; 32m0,052ESC [0m ESC [1; 32m 8216,00 kbESC [0m]]

Spróbuj użyć less --RAW-CONTROL-CHARS.

W tym przykładzie używam logtool , który drukuje dane wyjściowe przy użyciu kolorów.

Bez --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

Z opcją --RAW-CONTROL-CHAR (Wyobraź sobie, że jest w ładnych kolorach. Nie jestem też pewien, dlaczego ^Gto się wyświetla.):

$ head -20 /var/log/messages | logtool | less --RAW-CONTROL-CHARS
Mar 20 11:43:52 host1 rsyslogd: ^Glast message repeated 14 times
Stefan Lasiewski
źródło
2

To byłby błąd, gdyby lessnie ustawiono interpretacji ucieczek ANSI; szukać Rw $LESSOPTS. Jeśli chodzi o ustalenie, czy system wie, że twój terminal radzi sobie z kolorami, tput colorswyświetli albo liczbę obsługiwanych kolorów, albo -1jeśli nie obsługuje kolorów. (Należy pamiętać, że niektóre terminale mogą używać xtermzamiast xterm-colorich opisu, ale nadal obsługują kolory).

geekozaur
źródło
Chodzi o to, aby moja aplikacja wiedziała, że ​​nie należy pokolorować danych wyjściowych, jeśli program nie może wydrukować, powiedzmy, rejestrowania danych wyjściowych z zadania cron do pliku, nie trzeba rejestrować kolorowych danych wyjściowych, ale gdy uruchamiam ręcznie, lubię przeglądać wyjście kolorowe.
Angelo Vargas