We're an ISO27001:2013 Certified Supplier

blog-post-featured-image

Many shell commands can produce coloured output; for example, on most distributions the ls command shows files in colours according to the file type:

ls with colour

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 – the RAW_CONTROL_CHARS option discussed above
  • -i – searches within less are case-insensitive
  • -X – don’t clear the screen after using less
  • -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.