Team LiB
Previous Section Next Section

Hack 15. Colorize Files in Your Pager

As a Linux user you might have noticed that filenames appear in different colors when you type ls or dir. Yet when you pipe the colored file listing through a pager such as less, the pager ignores the colors and turns the output into black and white. You might notice this when you execute a commonly used command, such as ls -al | less.

Most Linux distributions are configured to display the files in various colors to make it easy to identify symbolic links, executable files, compressed files, and so on. If yours is not configured in such a way, there's an easy way to correct this. Type the following command:

$ alias ls='ls --color=auto'

This tells your system that every time you type the ls command, it will actually type ls --color=auto for you. Now type the command:

$ ls

You should see your files appear in different colors, according to their type. If you didn't see colored filenames, you might have a distribution that requires a slightly different switch. Try this instead:

$ alias ls='ls --color=tty'

Now type the command to test the color capability:

$ ls

Chances are that one or more alias definitions are already defined for you in one of the automatically executed login files. See the sidebar Bash Auto-Configuration Files for more information about how many popular distributions make these settings.

2.7.1. The Black-and-White Problem

Now here's the problem that might plague you at times. You want to view a list of files, so you issue the command ls -a. That command lists all the regular and hidden files, and all the files and directories appear in living color. Or perhaps you prefer to use the command ls -al that lists all regular and hidden files in a detailed single column. Once again, the files appear in living color.

When there are many files, the list scrolls off the screen. This is particularly troublesome on a text console that doesn't let you scroll back far enough to see the beginning of the list. What's a geek to do? The intuitive solution is to issue this command:

$ ls -al | less

This pipes the output of ls -al tHRough the less pager, which lets you scroll back and forth through the entire output of the ls -al command.

There's just one catch. All the pretty colors are gone. It is no longer easy to identify compressed files from executable files (and so on...) at a glance.

You don't see colors in the less pager for two reasons. First, less requires the -R command-line switch to display colors. That won't be enough for most Linux users, however. You can find out for yourself if adding the -R switch is all you need for your Linux distribution by typing this command:

$ ls -al | less -R

Did you see the list of files in color? Probably not. That's because most Linux distributions set up ls as an alias for the command ls --color=tty or ls --color=auto. These commands output color only when the destination is a terminal screen. When you pipe the output or redirect the output from ls, it turns off the color feature automatically.

There are at least three solutions to this problem.

2.7.2. Solution 1

Here's one way to fix the problem. The ls --color command does not care what the output is, whether it's a terminal screen, a redirection to another file, or a pipe to another program. One or more files in your system contain the commands to set the aliases (see the sidebar Bash Auto-Configuration Files, which includes information on where these settings are made for various distributions). Find the file on your system where you want to change the way the aliases are set. Look for the line that defines the color as auto or tty as the default, and change it to this (you might as well add the -R to less while you're at it):

alias ls='ls --color'
alias less='less -R'

By not specifying tty or auto, the ls command will output color no matter where the output is directed.

There's a catch to doing things this way, so before you edit the file that defines the alias command, try the technique manually so that you can see for yourself what the catch will be. Follow these steps to set the default behavior for both ls and less to support color, and then perform the piped output command to see a listing of files in color:

$ alias ls='ls --color'
$ alias less='less -R'
$ ls -al | less

There you gocolorized output in the less pager.

Now that ls automatically outputs color no matter where the output is directed, try this command to redirect the output of the colored directory list to a file:

$ ls -al > directory.txt

Now open the file with your favorite editor, and you should see all the codes used to colorize the text. For example, you might see something like this:

[[01;34mDesktop[[00m
[[01;31mEiosource-1.1-1.i386.rpm[[00m
[[01;34mGNUstep[[00m
[[00mHello[[00m
[[00mKernel-Win4Lin3-2.6.6.patch[[00m

Your editor doesn't interpret the codes to colorize your text. It simply shows you the codes that exist in the output of the command. This is not quite what you want when you redirect output to a file, is it?

So, here's a way to deal with the first solution. You can modify your alias settings so that the following command produces colorized output:

$ ls -al | less

When you don't want to produce colorized output, such as when you want to redirect the output to a file, you override the alias with a command like this, which specifies that ls should output color only if the destination is a terminal:

$ ls -al --color=auto > directory.txt

2.7.3. Solution 2

The second solution is precisely the opposite of the first. Leave the alias alone, as it is already set. When you get the hankering to view a long directory list through a pager, override the setting that restricts color output to terminals with this command:

$ ls -al --color | less -R

2.7.4. Solution 3

Neither of the previous solutions is the "Linux way"; that is, a way to customize and automate everything. So, here's a way to solve the problem like a true Linux hacker would. Define aliases to give you the choices you want while using shorthand commands. Here's one example, but it is by no means the only way to approach this. Edit the file where aliases are defined so that it contains these aliases:

alias ls='ls --color=auto'
alias lsp='ls --color | less -R'
alias dir='ls -al'
alias dirp='ls -al --color | less -R'

This way, you can issue a command such as ls -al > directory.txt, and the file won't be littered with color codes. Yet anytime you want to page through a full list of your files in living color, all you have to type is the command lsp or dirp.

Bash Auto-Configuration Files

Fedora Core sets default aliases in the /etc/profile.d/colorsls.sh file to:

alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'

Debian sets default aliases in the /etc/skel/.bashrc file to:

alias ls='ls --color=auto'

SUSE uses a complex /etc/bash.bashrc script that ends up setting the ls alias indirectly to:

alias ls='ls --color=tty'

Mandrake uses a complex set of files, and sets the default alias in /etc/profiles.d/alias.sh to:

alias ls='--color=auto'

Gentoo sets default aliases in /etc/skel/.bashrc to:

alias ls="ls --color=auto"


    Team LiB
    Previous Section Next Section