## 8.6. Color ls

The GNU ls command -- which is on a lot of systems, including Linux -- can display names in colors. For instance, when I enable color listings on my system, directory names are in dark blue, symbolic links are in sky blue, executable files (scripts, programs, etc.) are in green, and so on.

tcsh 's built-in ls -F command can display in colors, too. Just set color in your .cshrc to enable it, and configure it using `LS_COLORS` as described later in this section. You may also want to look at Section 8.6.4 for another way to configure colors if - - color doesn't seem to work.

### 8.6.1. Trying It

Go to http://examples.oreilly.com/upt3 for more information on: GNU ls

Has your system been set up for this? Simply try this command:

>     $ ls --color / /bin

If you don't get an error (ls: no such option -- color, or something similar), you should see colors. If you don't get an error, but you also don't get colors, try one of these commands, and see what you get:

>     $ ls --color=always / /bin | cat -v
>     ^[[00m/:
>     ^[[01;34mbin^[[00m
>     ^[[01;34mboot^[[00m
>        ...
>     ^[[01;34mvar^[[00m

>     /bin:
>     ^[[01;32march^[[00m
>     ^[[01;36mawk^[[00m
>     ^[[01;32mbasename^[[00m
>        ...

>     $ ls --color=yes / /bin | cat -v
>        ...same kind of output...

Those extra characters surrounding the filenames, such as `^[[01;34m` and `^[[00m`, are the escape sequences that (you hope) make the colors. (The cat -v (Section 12.4) command makes the sequences visible, if there are any to see.) The `^[` is an ESC character; the next `[` starts a formatting code; the `01` code means "boldface"; the semicolon (`;`) is a code separator; the `34` means "blue"; and the `m` ends the escape sequence. `^[[00m` is an escape sequence that resets the attributes to normal. If you see the escape sequences when you use `cat -v`, but you haven't gotten any highlighting effects when you don't use it, there's probably some kind of mismatch between your termcap or terminfo entry (Section 5.2) (which should define the sequences) and the color database (see later in this section). If you don't see the escape sequences at all, take a look at Section 8.6.4 for another way to configure color ls.

### 8.6.2. Configuring It

How are the colors set? Both GNU ls and tcsh's ls -F use the LS_COLORS environment variable to decide how to format filenames. Here's a sample (truncated and split onto three lines for printing):

>     $ echo $LS_COLORS
>     LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:
>     bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:
>     *.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:
>         ...

The LS_COLORS value is a series of `item`=attribute values with a colon (:) between each pair. For instance, `fi=00` means that files have the attribute (color) 00; `di=01;34` means that directories have the attributes 01 (bold) and 34 (blue); and `*.exe=01;32` means that filenames ending with .exe have the attributes 01 (bold) and 32 (green). There can be up to three numbers. The first is an attribute code (bold, underscore, etc.); the second is a foreground color; the third is a background color. So, `01;37;41` indicates boldfaced white foreground (37) text on a red background (41).

The format is fairly obtuse, so you won't want to set LS_COLORS directly if you don't have to. The easy way to set it is with the dircolors command -- typically in a shell setup file (Section 3.3):

`eval` Section 27.8`'...'` Section 28.14

>     eval `dircolors`

There, dircolors is reading the default database and outputting a command to set LS_COLORS. What if you don't want the default database settings? You can make your own. An easy place to start is with dircolors -p, which outputs a copy of the database. You can redirect the output to a file; a good option is to use a .dircolorsrc file in your home directory. Then take a look at it:

>     $ dircolors -p > $HOME/.dircolorsrc
>     $ cat $HOME/.dircolorsrc
>         ...
>     # Below should be one TERM entry for each colorizable termtype
>     TERM linux
>         ...
>     TERM vt100

>     # Below are the color init strings for the basic file types. A color
>     # init string consists of one or more of the following numeric codes:
>     # Attribute codes:
>     # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
>     # Text color codes:
>     # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
>     # Background color codes:
>     # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
>     NORMAL 00     # global default, although everything should be something.
>     FILE 00       # normal file
>     DIR 01;34     # directory
>     LINK 01;36    # symbolic link
>         ...

>     # List any file extensions like '.gz' or '.tar' that you would like ls
>     # to colorize below. Put the extension, a space, and the color init string.
>     # (and any comments you want to add after a '#')
>     .tar 01;31 # archives or compressed (bright red)
>     .tgz 01;31
>         ...

The file starts with a listing of terminal type (Section 5.3) names that understand the color escape sequences listed in this file. Fortunately, the escape sequences are almost universal; there are some old terminals (like my old Tektronix 4106, I think . . . R.I.P.) that don't understand these, but not many. (If you have a different terminal or an odd terminal emulator, you can select a setup file automatically as you log in (Section 3.10).) The second section has a commented-out list of the attributes that these terminals recognize. You can use that list in the third section -- which has standard attributes for files, directories, and so on. The fourth section lets you choose attributes for files by their filename "extensions" -- that is, the part of the filename after the final dot (like .tar).

If you make your own database, you'll need to use it (again, typically in a shell setup file) to set LS_COLORS:

>     eval `dircolors $HOME/.dircolorsrc`

### 8.6.3. The -- color Option

For better or for worse, the way to activate color ls is by using the `--color` option on the command line. Because almost no one will want to type those characters every time they run ls, most users need to make an alias (Section 29.2, Section 29.4) for ls that runs `ls --color`. For example, here are the three aliases defined for bash on my Linux system:

>     alias l.='ls .[a-zA-Z]* --color=auto'
>     alias ll='ls -l --color=auto'
>     alias ls='ls --color=auto'

If you're using tcsh, setting the `color` variable to enable ls -F's color also arranges to send -- color=auto to regular ls.

The -- color option gives you three choices of when the ls output should be colored: -- color=never to never output color, -- color=always to always output color, and -- color=auto to only output color escape sequences if the standard output of ls is a terminal. I suggest using -- color=auto, because -- color=always means that when you pipe the output of ls to a printer or redirect it to a file, it will still have the ugly escape sequences you saw earlier in this article.

### 8.6.4. Another color ls

Some systems have another way to configure and use color ls. My FreeBSD systems use this scheme; if none of the configuration techniques described earlier work, use ls -G or set the `CLICOLOR` environment variable. If this works, you'll want to use the `LSCOLORS` environment variable to configure color information instead of `LS_COLORS` as described earlier. Spend a little time perusing your ls(1) manpage for further details if your ls seems to work this way, as configuring it is likely to be completely different from what we described previously.

--JP and DJPH

Copyright © 2003 O'Reilly & Associates. All rights reserved.