The Linux Page

Not losing the colors with "less" when doing a grep, ls, etc.

A bunch of fruits on a table with five smoothies

Unix in Colors

Whenever I run a command without piping it through less, I generally get colors.

This is true in this century that computer started to use more and more colors in the console. It's practical for all sorts of reasons.

However, you lose those nice colors when you want to use "less" to paginate the results. There are two reasons for that:

Terminal vs. Pipe

The fact is that many tools will check their stdout and determine whether it's a terminal or not. If not, it can generally be assumed that it's a file, a pipe, a variable, etc. and therefore a place where the color commands should not be sent because the next processing of the output would likely be badly affected by all the controls, square backet, and other terminal commands.

Actually, those commands are really very specific to the terminal and therefore should not be sent anywhere else. But of course, when you use less (or more) you are on the terminal so why not display the colors as expected?!

There are various potential problems, although frankly in generally this technique works great. So we do want to be able to print colors even to a pipe.

In case of the ls and grep commands, they both require the --color command line option for the color to stick even when the command gets piped:

ls --color
grep --color

Check the manual page of other commands you'd like to keep the colors from as it is not unlikely that they have suich an option and it can be worth it.

The effect of the --color is to skip the test to know how to handle stdout. It will just send the color automatically.

For those interested in how this is done under Linux, you use the isatty() function. Somthing like this:

bool use_color = isatty(); // true only if output is a TTY
if(strcmp(argv[idx], "--color") == 0)
    use_color = true; // force true

There are many other tests, but this gives you the basics. Specifically, the ls code tests whether the terminal actually supports colors. If not, it will again set the user_color parameter to false.

The command also let you assign colors to the various types it supports so there is quite a bit more to do than just this one test. But you're on your own for that code!

Keep Colors in "less"

Interestingly enough less removes the terminal codes by default. I find that ideology strange especially thinking that a file could include terminal codes that you'd liketo see interpreted by the terminal and not as control (such as "^[").

So in order to keep the colors, you must instruct "less" to display them as is. This is done with the "-r" command line option. The "-R" may work in your circumstances.

So to paginate the output of ls in color with less, you write:

ls -l --color | less -r

Notice how the two sides need an additional command line option to make this  work. If you only use the --color or the -r.