Bash – How to Emulate a TTY to Preserve Piped Color Output

bashcolorslesspipetty

When you pipe something through less, the program usually discards color codes because it's not outputting to a TTY. So you have to add --color=always to the options for it to work.

ls -l --color=always | less
grep -R asdf --color=always | less

What's worse is that sometimes things don't even support that option, so there's actually no way to force color output to a pipe.

Is there a (relatively) easy way to make less emulate a TTY so that I don't have to specify --color=always to every program when things get piped to it, and it automatically displays color output when possible?

Best Answer

It's not less that needs to change. The output of your other programs is being redirected to a pipe. Those programs detect that their output is not being sent to a tty and they disable their coloring. You're stuck with having to do something special with the source programs to color their output even when redirected to a pipe.

I think I have a solution for the programs that do not support a --color=always option. The unbuffer command creates a pty and sends the output of its argument program to that pty, therefore the argument program thinks its output is going to a tty and colors it.

I tried the following as an experiment and it worked. I couldn't think of any programs that color their output by default.

$ unbuffer ls --color=auto | cat

Also, don't you have to use the -r option with less to get it to display color? I also tried this:

$ unbuffer ls --color=auto | less -r
Related Question