Isso ocorre por design: programas que produzem saída colorida normalmente o fazem somente quando a saída vai para um terminal, não quando é enviada para um canal ou para um arquivo normal. A razão é que os dados enviados em um terminal são presumivelmente lidos por um ser humano, enquanto dados direcionados a um programa ou gravados em um arquivo provavelmente são analisados por algum programa, portanto ele não deve conter conteúdo estranho como sequências de escape que mudam de cor .
GNU ls exibe a saída colorida em um terminal quando você passa a opção --color (ou --color=auto ). Para forçar a saída colorida, independentemente do tipo de arquivo da saída padrão, passe --color=always ou --color=yes (eles são sinônimos). Esta convenção foi seguida por outros comandos, como o GNU grep, o FreeBSD grep, git diff , etc.
ls --colors=yes -l | less
Com a versão FreeBSD de ls (também encontrada no OSX, e disponível como colorls port no OpenBSD e NetBSD), passe a opção -G para exibir as cores quando a saída for um terminal. Defina o ambiente CLICOLOR_FORCE para exibir as cores, independentemente do tipo de arquivo de saída.
CLICOLOR_FORCE=1 ls -l | less