Coder Perfect

How do I output coloured text to a Linux terminal?

Problem

What is the best way to print colored characters to a Linux terminal that supports them?

How can I tell if a terminal accepts color codes?

Asked by Macha

Solution #1

ANSI color codes must be output. Note that not all terminals support this; if colour sequences are not supported, garbage will show up.

Example:

 cout << "\033[1;31mbold red text\033[0m\n";

033 is the ESC character, which is ASCII 27. The letter m is then followed by [, followed by zero or more numbers separated by ;, and finally the letter m. The numbers indicate which color and format should be used from that point forward.

The following are the color codes for the foreground and background:

         foreground background
black        30         40
red          31         41
green        32         42
yellow       33         43
blue         34         44
magenta      35         45
cyan         36         46
white        37         47

You can also make use of the following:

reset             0  (everything back to normal)
bold/bright       1  (often a brighter shade of the same colour)
underline         4
inverse           7  (swap foreground and background colours)
bold/bright off  21
underline off    24
inverse off      27

Other, less well-known codes can be found in the Wikipedia table.

Check the value of the TERM environment variable to see if your terminal supports color sequences. It should specify the type of terminal that was utilized (e.g. vt100, gnome-terminal, xterm, screen, …). Then look it up in the terminfo database and see what colors are available.

Answered by Thomas

Solution #2

I created a C++ class that may be used to change the output’s foreground and background colours. This sample programme shows how to output This ->word- is red. and format it so that the word’s foreground colour is red.

#include "colormod.h" // namespace Color
#include <iostream>
using namespace std;
int main() {
    Color::Modifier red(Color::FG_RED);
    Color::Modifier def(Color::FG_DEFAULT);
    cout << "This ->" << red << "word" << def << "<- is red." << endl;
}
#include <ostream>
namespace Color {
    enum Code {
        FG_RED      = 31,
        FG_GREEN    = 32,
        FG_BLUE     = 34,
        FG_DEFAULT  = 39,
        BG_RED      = 41,
        BG_GREEN    = 42,
        BG_BLUE     = 44,
        BG_DEFAULT  = 49
    };
    class Modifier {
        Code code;
    public:
        Modifier(Code pCode) : code(pCode) {}
        friend std::ostream&
        operator<<(std::ostream& os, const Modifier& mod) {
            return os << "\033[" << mod.code << "m";
        }
    };
}

You might want to give the class some extra features. It is possible, for example, to use the color magenta as well as boldface styles. Simply add another member to the Code enumeration to accomplish this. This is an excellent resource.

Answered by Joel Sjögren

Solution #3

To output any color, you must first ensure that you are in a terminal:

[ -t 1 ] && echo 'Yes I am in a terminal'  # isatty(3) call in C

Then you must examine the terminal’s capacity to see if it can support color.

On Linux-based computers with terminfo, you can get a list of supported colors.

Number_Of_colors_Supported=$(tput colors)

On BSD-based systems with termcap, you can get a large number of available colors.

Number_Of_colors_Supported=$(tput Co)

Then make your choice:

[ ${Number_Of_colors_Supported} -ge 8 ] && {
    echo 'You are fine and can print colors'
} || {
    echo 'Terminal does not support color'
}

BTW, with ESC characters, do not utilize coloring as previously mentioned. Use the usual call to terminal feature, which will assign you the CORRECT colors for the terminal.

fg_black="$(tput AF 0)"
fg_red="$(tput AF 1)"
fg_green="$(tput AF 2)"
fg_yellow="$(tput AF 3)"
fg_blue="$(tput AF 4)"
fg_magenta="$(tput AF 5)"
fg_cyan="$(tput AF 6)"
fg_white="$(tput AF 7)"
reset="$(tput me)"
fg_black="$(tput setaf 0)"
fg_red="$(tput setaf 1)"
fg_green="$(tput setaf 2)"
fg_yellow="$(tput setaf 3)"
fg_blue="$(tput setaf 4)"
fg_magenta="$(tput setaf 5)"
fg_cyan="$(tput setaf 6)"
fg_white="$(tput setaf 7)"
reset="$(tput sgr0)"
echo -e "${fg_red}  Red  ${fg_green} Bull ${reset}"

Answered by Alex

Solution #4

You can use escape characters, as others have said. To make things easier, you can use my header:

#ifndef _COLORS_
#define _COLORS_

/* FOREGROUND */
#define RST  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"
#define KBLU  "\x1B[34m"
#define KMAG  "\x1B[35m"
#define KCYN  "\x1B[36m"
#define KWHT  "\x1B[37m"

#define FRED(x) KRED x RST
#define FGRN(x) KGRN x RST
#define FYEL(x) KYEL x RST
#define FBLU(x) KBLU x RST
#define FMAG(x) KMAG x RST
#define FCYN(x) KCYN x RST
#define FWHT(x) KWHT x RST

#define BOLD(x) "\x1B[1m" x RST
#define UNDL(x) "\x1B[4m" x RST

#endif  /* _COLORS_ */

The following is an example of how to use the header macros:

#include <iostream>
#include "colors.h"
using namespace std;

int main()
{
    cout << FBLU("I'm blue.") << endl;
    cout << BOLD(FBLU("I'm blue-bold.")) << endl;
    return 0;
}

Answered by gon1332

Solution #5

A typical ANSI color code, in my opinion, is

"\033[{FORMAT_ATTRIBUTE};{FORGROUND_COLOR};{BACKGROUND_COLOR}m{TEXT}\033[{RESET_FORMATE_ATTRIBUTE}m"

is made up of (name and codec)

It’s simple to colorize a string “I am a banana!” with forground color “Yellow” and background color “Green” using this information.

"\033[0;33;42mI am a Banana!\033[0m"

Colorize can also be done with a C++ library.

auto const& colorized_text = color::rize( "I am a banana!", "Yellow", "Green" );
std::cout << colorized_text << std::endl;

Here are some more FORMAT ATTRIBUTE samples.

Answered by Feng Wang

Post is based on https://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal