Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Colour output of program run under BASH [closed]

I need to be able to be able to make some text on terminal more noticeable, and what I thought was to make the text colored. Either the actual text, or the space in each letter's rectangle-thingy (think vi's cursor). The only two extra specs that I think are important for my application are : the program should be distro-independent (a certainty is that the code will only be run under BASH), and it shouldn't output extra characters when writing to a file (either from the actual code, or when piping the output)

I searched the web for some info, but I could only find info for the deprecated cstdlib (stdlib.h), and I need (actually, it's more of a "want") to do it using the functionality of iostream.

like image 277
Patrunjel Avatar asked Mar 30 '12 12:03

Patrunjel


People also ask

How do I change the color of my bash output?

For example, if you wanted to print green text, you could do the following: #!/bin/bash # Set the color variable green='\033[0;32m' # Clear the color after that clear='\033[0m' printf "The script was executed ${green}successfully${clear}!"

Can colorized output be captured via shell redirect?

Redirecting doesn't strip colors, but many commands will detect when they are sending output to a terminal, and will not produce colors by default if not.


2 Answers

Most terminals respect the ASCII color sequences. They work by outputting ESC, followed by [, then a semicolon-separated list of color values, then m. These are common values:

Special
0  Reset all attributes
1  Bright
2  Dim
4  Underscore   
5  Blink
7  Reverse
8  Hidden

Foreground colors
30  Black
31  Red
32  Green
33  Yellow
34  Blue
35  Magenta
36  Cyan
37  White

Background colors
40  Black
41  Red
42  Green
43  Yellow
44  Blue
45  Magenta
46  Cyan
47  White

So outputting "\033[31;47m" should make the terminal front (text) color red and the background color white.

You can wrap it nicely in a C++ form:

enum Color {
    NONE = 0,
    BLACK, RED, GREEN,
    YELLOW, BLUE, MAGENTA,
    CYAN, WHITE
}

std::string set_color(Color foreground = 0, Color background = 0) {
    char num_s[3];
    std::string s = "\033[";

    if (!foreground && ! background) s += "0"; // reset colors if no params

    if (foreground) {
        itoa(29 + foreground, num_s, 10);
        s += num_s;

        if (background) s += ";";
    }

    if (background) {
        itoa(39 + background, num_s, 10);
        s += num_s;
    }

    return s + "m";
}
like image 192
orlp Avatar answered Sep 20 '22 00:09

orlp


Here's a version of the code above from @nightcracker, using stringstream instead of itoa. (This runs using clang++, C++11, OS X 10.7, iTerm2, bash)

#include <iostream>
#include <string>
#include <sstream>

enum Color
{
    NONE = 0,
    BLACK, RED, GREEN,
    YELLOW, BLUE, MAGENTA,
    CYAN, WHITE
};

static std::string set_color(Color foreground = NONE, Color background = NONE)
{
    std::stringstream s;
    s << "\033[";
    if (!foreground && ! background){
        s << "0"; // reset colors if no params
    }
    if (foreground) {
        s << 29 + foreground;
        if (background) s << ";";
    }
    if (background) {
        s << 39 + background;
    }
    s << "m";
    return s.str();
}

int main(int agrc, char* argv[])
{
    std::cout << "These words should be colored [ " <<
        set_color(RED) << "red " <<
        set_color(GREEN) << "green " <<
        set_color(BLUE) << "blue" <<
        set_color() <<  " ]" << 
        std::endl;
    return EXIT_SUCCESS;
}
like image 37
Patrick Sanan Avatar answered Sep 20 '22 00:09

Patrick Sanan