1

I found these ways, for example, to output colored text in a simple way to the screen:

RED="\033[0;31m" # Red color (via ANSI escape code);
NC='\033[0m' # No color (via ANSI escape code);
echo -e "${RED}This text is red. ${NC}" # -e flag allows backslash escapes;

or:

printf '\e[1;34m%-6s\e[m' "This is blue text"

I also found:

tput setaf 1; echo "this is red text"

But I never used tput and I'm not sure it's shipped with all major distros (Debian, CetnOS, Arch, and so forth).

My question

How to output colored text in a given named, common color (like "Red") in a simple way I could count on to work on all major distros, without using "messy" color codes?

5
  • 1
    I think the ANSI escape sequences (used for your RED and NC variables) work in most major linux distros. I have tested in several distros (and found that they work).
    – sudodus
    Commented Jan 1, 2019 at 10:05
  • Possible duplicate of How can I list the available color names? Commented Jan 1, 2019 at 10:38
  • 1
    @ThomasDickey I miss why it is a duplicate; I don't want to list anything... Just using some global (distro-agnostic) simple command with simply-named color...
    – user149572
    Commented Jan 1, 2019 at 10:50
  • 1
    The linked duplicate is different. Commented Jan 1, 2019 at 11:31
  • 1
    @ctrl-alt-delor the answer seems more complete than yours here and answers fully this question Commented Jan 1, 2019 at 11:48

2 Answers 2

8

You can use tput.

I'm not sure [that tput is] shipped with all major distros

It's part of ncurses, and packaged with it on all three of those operating systems and more.

So tput setaf will work across a broad range of systems, with the obvious proviso that the requisite package needs to be installed.

The downside is that using it still ends up employing "non-word colour codes", as the numbers that one supplies are the 8 standard colours indices from ECMA-48 (with a possible extra 8 de facto standard colours on some terminal emulators, and up to 256 colours by using ISO 8613-6 Indexed colour on some).

On the gripping hand, the 8 standard ECMA-48 colours are well known, and what (for example) "6" means as a colour number is not all that obscure.

You can also use setterm.

However, if you are looking for more human-readable commands that use names rather than numbers, albeit in English only, there are widespread tools that can do that, too. One such is setterm, which is used like this:

% setterm --foreground red ; echo "this is red text"

The setterm that you will find in the repositories of Debian, Fedora, and Arch is the one from the util-linux toolset. That command relies upon various Linux-specific things for some of the other actions that the command can perform, and it of course is not available on the BSDs. The toolset is Linux-specific and not portable, as its name tells one.

Also, whilst its manual page claims that the terminfo database is consulted, changing colours is one of quite a few cases where the actual program does not work as documented. It does not consult the setaf and setab capabilities in terminfo. Rather, the program hardwires the ECMA-48 SGR 30–37,39,40–47,49 control sequences.

Moreover, it does not support the additional 8 de facto standard colour indices from 8 to 15. It hasn't been kept up to date with the capabilities of the Linux KVT, which does support the "bright" colours, and which nowadays at least accepts ISO 8613-6 Indexed and Direct colour control sequences (albeit that it does not actually implement full 24-bit colour).

Furthermore, because of a bug in that very hardwiring code, the version of util-linux setterm in Debian Stable does not emit the right SGR sequences when setting colours.

  • setterm. User Commands. Michael Kerrisk. 2014-05.

… even on the BSDs, now.

Finding that bug was one of the things that inspired me to write a setterm replacement, which (coincidentally) I have just done. I didn't copy the (moderate amount of) stuff that was idiosyncratic to Linux and to its kernel virtual terminals. And conversely I did add some ECMA-48 stuff that has been around for several decades that the util-linux setterm does not have (because the Linux KVT did not support that part of ECMA-48, and setterm has its roots in being specific to the Linux KVT). I also added UTF-8, support for the actual 8-bit C1 control characters (as well as their 7-bit aliases), and ISO 8613-6 Direct colour (if the terminal type is known to support it).

And of course, this implementation does exist for the BSDs:

% uname ; printenv TERM
FreeBSD
rxvt
% TERM=ansi setterm --7bit --foreground red|hexdump -C 
00000000  1b 5b 33 31 6d                                    |.[31m|
00000005
% setterm --7bit --foreground red|hexdump -C 
00000000  1b 5b 33 38 3b 35 3b 31  6d                       |.[38;5;1m|
00000009
% setterm --7bit --foreground 192|hexdump -C 
00000000  1b 5b 33 38 3b 35 3b 31  39 32 6d                 |.[38;5;192m|
0000000b
% setterm --7bit --foreground '#00BEC119'|hexdump -C
00000000  1b 5b 33 38 3b 35 3b 31  39 31 6d                 |.[38;5;191m|
0000000b
% TERM=vte-256color setterm --7bit --foreground '#00BEC119'|hexdump -C 
00000000  1b 5b 33 38 3b 32 3b 31  39 30 3b 32 35 3b 31 39  |.[38;2;190;25;19|
00000010  33 6d                                             |3m|
00000012
% TERM=ansi setterm --7bit --foreground 'bright red' --background 'bright yellow'|hexdump -C
00000000  1b 5b 39 31 6d 1b 5b 31  30 33 6d                 |.[91m.[103m|
0000000b
% setterm --7bit --foreground 'bright red' --background 'bright yellow'|hexdump -C
00000000  1b 5b 33 38 3b 35 3b 39  6d 1b 5b 34 38 3b 35 3b  |.[38;5;9m.[48;5;|
00000010  31 31 6d                                          |11m|
00000013
%

It is in version 1.39 of the nosh toolset, in the terminal management package with the name console-control-sequence, allowing one to have this side-by side with util-linux. The setterm shim name for the command is provided by a separate shims package. So if you write something using setterm to change colours and someone claims that that is Linux-specific, you know where to direct them. I've put the manual page up as a preview.

  • Jonathan de Boyne Pollard (2018). setterm. nosh Guide. Softwares.

Get the SGR codes right, by the way.

SGR 0 is not "no colour". SGR 0 resets all colours and attributes. There actually is not a concept of "no" colour. There is a concept of the "default" colour, set by SGR 39 and SGR 49:

% setterm --7bit --foreground default --background default|hexdump -C
00000000  1b 5b 33 39 6d 1b 5b 34  39 6d                    |.[39m.[49m|
0000000a
%

1
  • 1
    Looks like the original jdebp.eu site is no more and seems like this is the page on the new site. Would I be correct in assuming that the easiest way to get your version of the setterm command under a Linux distro such as Fedora would be to build nosh from the repo that you have hosted on github here? Or if I only am really interested in the additional setterm functionality is there an easier way to just get that by itself?
    – zpangwin
    Commented Aug 27, 2021 at 21:15
3

Codes (ANSI colour codes)

The codes are not distro dependent. They are terminal dependent. Some terminals will not support them. However they are probably supported by most.

Names

Use variables to give names e.g.

red="$(tput setaf 1)"
echo "${red}hello"

note: don't use capitals for shell variables, capitals should be reserved for environment variables.

Names and codes

The codes refer to a colour number. the colour for each number is defined by the terminal, and in non-standard. The user can change it.

1
  • Hi ! By "codes" on the very start, you meant ANSI escape-codes, right?
    – user149572
    Commented Jan 2, 2019 at 18:14

You must log in to answer this question.