There are two problems here:
- Commands like
ls
—which auto-detect the colour support— don't find support from pipes
less
is set to just display colour codes by default.
Both can be overcome but it's a bit clunky:
ls --color=always | less -R
This isn't ls
specific. Many commands that support colour also have an override argument.
A slightly more in-depth answer is that ls
is checking whether or not its STDOUT belongs to a real terminal or not. When you pipe things around, the STDOUT is set to the STDIN of the next command.
You can see this at work in the ls
source code. It's using the isatty
command (a core POSIX interface) to work out what the situation is:
Are colours on by default:
print_with_color = (i == color_always
|| (i == color_if_tty
&& isatty (STDOUT_FILENO)));
Do we try to output in multiple columns:
if (format == long_format)
format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
//...
if (isatty (STDOUT_FILENO))
{
format = many_per_line;
set_quoting_style (NULL, shell_escape_quoting_style);
qmark_funny_chars = true;
}
else
{
format = one_per_line;
qmark_funny_chars = false;
}
grep
does a very similar thing, unless explicitly overridden, it'll detect colour support, with isatty
:
color_option = isatty (STDOUT_FILENO) && should_colorize ();
grep --color=always "search string" * | less -R
but I tend to usemost
nowadays instead ofless
. ALSO: gnu.org/software/src-highlite is a color highlighter (less works too)python-pygments
?less