So You Like Color--The Mysterious ^[[ Characters

 in
Learn how to make the text in your xterm blink magenta against a cyan background--even in your C programs.
A Demo of Colors

The following program asks the user to play with attributes and colors and then shows a text string in those colors and with those attributes. I usually use it to find the best combination of colors for my GUIs.


#include <stdio.h>

#define RESET		0
#define BRIGHT 		1
#define DIM		2
#define UNDERLINE 	3
#define BLINK		4
#define REVERSE		7
#define HIDDEN		8

#define BLACK 		0
#define RED		1
#define GREEN		2
#define YELLOW		3
#define BLUE		4
#define MAGENTA		5
#define CYAN		6
#define	WHITE		7

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

char *attrs[] = {"NORMAL", "BRIGHT", "DIM", "UNDERLINE", "BLINK",
		 "REVERSE", "HIDDEN", "EXIT"};
char *colors[] = {"BLACK", "RED", "GREEN", "YELLOW", "BLUE", "MAGENTA",
		 "CYAN", "WHITE", "EXIT"};
void textcolor(int attr, int fg, int bg);
int print_menu(char *array[], int n_options, char *title);
int main()
{	int attr, fg, bg;
	int attr_size, colors_size;
	
	attr_size = ARRAY_SIZE(attrs);
	colors_size = ARRAY_SIZE(colors);
	while(1)
	{	printf("\n");
		attr = print_menu(attrs, attr_size, "Choose the attr you want:");
		if(attr == attr_size - 1)
			break;
		fg = print_menu(colors, colors_size, "Choose the foreground you want:");
		if(attr == colors_size - 1)
			break;
		bg = print_menu(colors, colors_size, "Choose the background you want:");
		if(attr == colors_size - 1)
			break;
		printf("\n");
		textcolor(attr, fg, bg);	
		printf("This is what you get if you use the combination %s attribute %s foreground and %s
 background", attrs[attr], colors[fg], colors[bg]);
		textcolor(RESET, WHITE, BLACK);
		system("clear");
	}
	return 0;
}

int print_menu(char *array[], int n_options, char *title)
{	int choice, i;
	for(i = 0;i < n_options; ++i)
		printf("%d.%s\n", i, array[i]);
	printf("%s", title);
	scanf("%d", &choice);
	return choice;
}		
void textcolor(int attr, int fg, int bg)
{	char command[13];

	/* Command is the control command to the terminal */
	sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
	printf("%s", command);
}

The Catch

So, what's the catch? If producing colors and attributes for text is so easy, why do people waste their time writing huge programs in curses, which in turn queries terminfo in a complex way? As we know, many terminals are out there that have few capabilities. Others don't recognize these escape codes or need different codes entered to achieve the same effect. So, if you want a portable program that can run on various terminals with the same or reduced functionalities, you should use curses. Curses uses terminfo to find the correct codes to accomplish these types of tasks across various terminals. Terminfo is a large database that contains information about the various functionalities of different terminals.

But, if you simply want to write a program that produces color on a Linux console or in an xterm window, you can use the escape sequences above to do it easily. The Linux console mostly emulates vt100, so it recognizes these escape sequences.

With tput

However, there is a way to query the terminfo database for the information you need and do the work yourself. tput is the command that queries the database and executes the functionality you specify. The two capabilities setf and setb are useful to set foreground and background colors. For example, use the following to set the foreground color to red and the background color to green:


	tput setf 4	# tput setf {fg color number}
	tput setb 2	# tput setb {bg color number}

These commands can be used in shell scripts wherever you want. See the tput man page for additional capabilities of tput. The terminfo man pages contain a lot of information regarding terminal capabilities, how to get and set their values and more. There are two terminfo man pages: man 5 terminfo describes the terminfo database, and man 3ncurses terminfo describes the C functions that use the database.

Here are the numbers to be passed as arguments to tput setf and tput setb and their corresponding colors:

  • 0 Black

  • 1 Red

  • 2 Green

  • 3 Yellow

  • 4 Blue

  • 5 Magenta

  • 6 Cyan

  • 7 White

Resources

The Text-Terminal-HOWTO

Man pages for tput and terminfo.

Copyright (c) 2001, Pradeep Padala. Originally published in Linux Gazette issue 65. Copyright (c) 2001, Specialized Systems Consultants, Inc.

Pradeep Padala has a BE (equivalent to BS) in Computer Science and Engineering. His interests include solving puzzles and playing board games.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Bypass the need for CTRL-V ESC

Themilkman's picture

If you want to omit the CTRL-V ESC key sequence you can use \033 instead.

So the lines would read echo "\033[0;31;40m In Color"
and echo "\033[0;37;40m"

This makes it easier to type and to have in scripts.

Excellent post

Chris Hampson's picture

A fantastic post, I'm just about to do some scripts involving interpreting these colour codes from the logs from the screen utility, this page was invaluable.

Keep up the good work :-)

Cool Tutorial, but...

Matt Cudmore's picture

Cool tutorial, but, I noticed that in the two coding examples you #define BLINK as 4, when it's actually supposed to be '5'

It's just a small type-o, but I thought I'd let you know just incase someone (such as myself) tries to learn from one of the examples without first looking to the list that correctly defines BLINK as 5.

Inspired me to write a library

John Holden's picture

It's been a slow day before exams started, so I went and wrote a C header I've named SimpleColors after reading this article: CVS (tarball). Great information!

This link is broken!

Anonymous's picture

This link is broken!

awesome

herbmaster's picture

OMG, this is awesome. I've been wondering for about three years how to do colors in c(besides using ncurses). I just happened to be bored and decided to checkout lj's website since I have a subscription and really like the mag.

I think the editors are retarded for not putting this stuff in the magazine. I mean, I have to look at a computer monitor 12 hours a day and I'd really rather go home and read this stuff from the print mag.

But anyway, awsome article Pradeep. Thanks!

bugs in code

Anonymous's picture

In your while loop, the second and third if statements are incorrect. It looks like you copied/pasted the first statement and did not change the conditions -- you are comparing attr when it should be fg and then bg.

RE: bugs in code

Anonymous's picture

Sorry, forgot to mention that is for the "Demo of Colors" program.

Will Linux make computers soo

Anonymous's picture

LINUX is no brand

webdesign hamburg's picture

and never will be. So Linux as a organization could not exist. And you cannot build real material things over the web, cause your hands doesnt fit into the cables :)

Re:

A@A's picture

In USSR was not any commercical company. But this counrty was better than USA.
Communism rulezzz!

Such a thing could be

gentoo user's picture

Such a thing could be written by the person who never lived in both countries nor US nor USSR. It seems the author of the previous comment is a teen who grown up in Ukraine as an independent country and considers that USSR was a communist state... Funny :)

look it up

Anonymous's picture

Actually the Ukraine beeing a part of the USSR is not that long ago! They became independant 1991.

cool article. i finally under

Anonymous's picture

cool article. i finally understood colors... although a msg about that it is not possible to paste the escape sequence into your terminal would be good.

But what about outputting to a file?

Boom's picture

Hi, I use escape sequences in my program but then if I redirect the output to a file, I start seeing all these escape characters in there. Is there a way that I can disable this functionality when outputting to a file?

istty

sde's picture
White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState