Many shell commands can produce coloured output; for example, on most distributions the ls
command shows files in colours according to the file type:
We tend to take the colour for granted, and interpret it subconsciously. We only really notice it when it’s missing – but if the output of ls
is piped through less
, the colours are lost.
Adding Colour After Pipe
There are two switches to less
that can help us. By default, less
displays control characters as caret-character; for example, control-A would be displayed as ^A
. The ‑‑raw‑control‑chars
(or -r
) switch suppresses the translation of control characters, and in the example above would send control-A to the screen. This switch allows the escape sequences that control colour to pass unchanged, and thus the coloured output is retained.
But there’s a catch. Some escape sequences will affect the appearance of the screen, and less
can’t know about the effect they may have on the display. As a result, less
doesn’t know exactly what the display looks like, which may lead to odd behaviour such as lines being split in the wrong place.
The alternative is the ‑‑RAW‑CONTROL‑CHARS
(or -R
) switch – yes, it is an upper-case long option. This is similar to the -r
switch above, but only the ANSI colour escape sequences are output unprocessed (so a control-A will still be displayed as ^A
). This allows less
to have a much better understanding of the display, and should avoid line splitting issues and similar.
But there’s another catch. You may find that the following command does not, in fact, show any colour in the output:
$ ls | less -R
If that’s the case, check how ls
is aliased:
$ alias ls alias ls='ls --color=auto'
The –-color=auto
will cause ls to output colo(u)r only when stdout
is a terminal. That means that ls
alone shows colour, but when the output is piped to another command, it is suppressed. That can be helpful – no escape sequences are embedded in files if the output is redirected to a file – but it also means no escape sequences, and thus no colour, when the output is piped to less
.
The fix: explicitly tell ls to output colour:
$ ls --color | less -R
Automating
You can also set the environment variable LESS
to hold the switches you want set by default:
$ echo $LESS -RiXj5
That means that every time less is run, it will have the following options set:
-R
– theRAW_CONTROL_CHARS
option discussed above-i
– searches withinless
are case-insensitive-X
– don’t clear the screen after usingless
-j5
– put the result of searches on the fifth line of the screen where possible
With that environment variable set, this will produce a coloured output:
$ ls --color | less
Day To Day Use
I have the following in my ~/.bash_profile
:
export LESS==RiXj5 alias ls='ls --color'
That give me colour directory listings when piped through less
. On the very odd occasion I might want to write a directory listing to a file or similar, I use
ls --color=never > myfile
Was This Linux Tip Useful?
Let us know in the comments below.
Nice, that -R flag is really not obvious!