| « Dancing girl optical illusion | Spam filtering enhancement to Horde accepted » |
Configuring LS_COLORS
April 11th, 2008The directory lister under UNIX is called ‘ls’. In the deep and distant past this was a very black and white affair. GNU has changed all that by introducing an environment variable called LS_COLORS which allows you to set the colours of files based on extension, permissions and file type.
As usual the instructions on how to configure it are locked away so that only a privileged few know how to configure them. When I started looking for this holy grail, I came across some poor guy who had worked it out through trial and error. I thought that there must be some documentation, somewhere on the internet. But, no! I have pieced together all the information I could find from mail list postings, support forums and when I eventually found it, the source code.
I will attempt to describe what I have discovered on my journey so that others may start from here with a better understanding of how LS_COLORS works.
The BSD implementation of ls used in BSD, FreeBSD and MacOS is slightly different. It uses a set or unset CLICOLOR environment variable or the ls command line switch -G to indicate whether to use the colours defined in the environment variable LSCOLORS. Whereas GNU’s ls uses the command line switch −−colour and the environment variable LS_COLORS instead (Thanks Gilles).
If you do not specify a colour to use then the default will be used, which is why unsetting LS_COLORS has no visible effect. The defaults can be obtained by running the dircolors command.
dircolors --print-database
The database in question is a globally readable file which can be overridden depending on your terminal type. The database file is initially set to /etc/DIR_COLORS then overridden with one of the following. The first being the least precedent and the last being the most.
/etc/DIR_COLORS.$TERM/etc/DIR_COLORS.$TERM$HOME/.dircolors$HOME/.dircolors.$TERM$HOME/.dir_colors$HOME/.dir_colors.$TERM
This configuration file has several options:
- COLOR - either tty (add colour to ls when output is on the command line), all (all colours to ls on the command line and when piping i.e.
ls > file.txtwill have colour coding information in it) and none (switch off). - OPTIONS - strictly not related to LS_COLORS. This allows you to add extra options to the ls command.
- TERM - one line per terminal type that supports colour.
- EIGHTBIT - 1 (on) or 0 (off) to allow 8-bit output.
- and finally the colour definitions for file type and file extensions.
On most systems the ls command has been aliased to use the coloured option by default:
alias "ls=ls --color=auto"
The LS_COLORS environment variable is a colon separated list of key=colour pairs. There are 2 types of key: file types and file extensions.
Below is a list of all the keys (that I know of!). Thanks to Bartman for his starter page.
| no | NORMAL, NORM | Global default, although everything should be something |
| fi | FILE | Normal file |
| di | DIR | Directory |
| ln | SYMLINK, LINK, LNK | Symbolic link. If you set this to ‘target’ instead of a numerical value, the color is as for the file pointed to. |
| pi | FIFO, PIPE | Named pipe |
| do | DOOR | Door |
| bd | BLOCK, BLK | Block device |
| cd | CHAR, CHR | Character device |
| or | ORPHAN | Symbolic link pointing to a non-existent file |
| so | SOCK | Socket |
| su | SETUID | File that is setuid (u+s) |
| sg | SETGID | File that is setgid (g+s) |
| tw | STICKY_OTHER_WRITABLE | Directory that is sticky and other-writable (+t,o+w) |
| ow | OTHER_WRITABLE | Directory that is other-writable (o+w) and not sticky |
| st | STICKY | Directory with the sticky bit set (+t) and not other-writable |
| ex | EXEC | Executable file (i.e. has ‘x’ set in permissions) |
| mi | MISSING | Non-existent file pointed to by a symbolic link (visible when you type ls -l) |
| lc | LEFTCODE, LEFT | Opening terminal code |
| rc | RIGHTCODE, RIGHT | Closing terminal code |
| ec | ENDCODE, END | Non-filename text |
| *.extension | Every file using this extension e.g. *.jpg |
The keys (above) are assigned a colour pattern which is a semi-colon separated list of colour codes.
| Effects | |
| 00 | Default colour |
| 01 | Bold |
| 04 | Underlined |
| 05 | Flashing text |
| 07 | Reversetd |
| 08 | Concealed |
| Colours | |
| 30 | Black |
| 31 | Red |
| 32 | Green |
| 33 | Orange |
| 34 | Blue |
| 35 | Purple |
| 36 | Cyan |
| 37 | Grey |
| Backgrounds | |
| 40 | Black background |
| 41 | Red background |
| 42 | Green background |
| 43 | Orange background |
| 44 | Blue background |
| 45 | Purple background |
| 46 | Cyan background |
| 47 | Grey background |
| Extra colours | |
| 90 | Dark grey |
| 91 | Light red |
| 92 | Light green |
| 93 | Yellow |
| 94 | Light blue |
| 95 | Light purple |
| 96 | Turquoise |
| 97 | White |
| 100 | Dark grey background |
| 101 | Light red background |
| 102 | Light green background |
| 103 | Yellow background |
| 104 | Light blue background |
| 105 | Light purple background |
| 106 | Turquoise background |
| 107 | White background |
Most of the defaults are all right and not really worth changing. By default, executable directories show up as white on a light green background and normal directories which are blue on a black background. Both of these settings make your eyes go funny! So here is how to change just them.
LS_COLORS="ow=01;90:di=01;90"
export LS_COLORS
The above snippet changes both directories colours to grey.
Just as an aside, the easiest way to remap your colours is via the client control interface. I use PuTTY which allows you to redefine the terminal colour settings, but I think I’ll save that for another block entry!
34 comments
Well, it isn’t too secret. Try here:
http://dailypackage.fedorabook.com/index.php?/archives/109-Wednesday-Why-Colour-ls.html
I don’t think that your reference goes anywhere near describing how to do “Configuring LS_COLORS” but I’ll allow it in for two reasons:
1) the fact that anyone makes a comment is nice!
2) It’s another link to LS_COLORS which is a bit of a complicated affair, so the more links the better.
Added
I know that I get about 400 page views (per month) of this article, but if I mention affair, will I get all the porn hunters looking here? Oh no, I’ve mentioned porn does that mean I’ll get even more? I’ll analyse the blog stats over the next couple of months and let you know… (in another blog!)
i’ve searched in vain for the answer to this: I want to remove sg colors BUT have it use the extension colors instead i.e. ignore the sticky bit. setting sg=00 or removing it from ~/.dir_colors just makes those files black-n-white without the pretty colors by extension.
thanks for any help.
I’m afraid Ri you are out of luck. The sticky bit takes precedence over the other file types. Once “ls” sees that the file is sticky the extension settings are never read.
It’s an interesting request, you may want to email the GNU team and add it as a feature request or bug.
Try here: GNU FileUtils Project
This tut was very useful for me and my eyes. I almost went blind staring at blue letters. Many thanks for you’re effort..
I see that you can choose file extensions to color, but is there a way to color hidden files for when i do ‘ls -a’ like ‘.cshrc’? It doesn’t accept ‘.*’ as a valid entry.
Thanks for your great tip! It made my shell colorful!
I’ve known and used ansi color sequences for a long time now, and this is the first reference to the ‘Extra colours’ that I’ve ever seen.
Sure enough, I tried them out and they all work! Awesome. (now I’m gonna waste a good chunk of time seeing how I can further customize all my syntax highlighting, LS_COLORS, zsh completion menu colors, etc etc…)
Where did you find out about these?
Thanks for good knowledge.
it’s very useful way to change color.
Since your solution of :
LS_COLORS="ow=01;90:di=01;90″
export LS_COLORS
overwrites a possible existing configuration of LS_COLORS, you can juste substitute the existing definition with sed (stream editor) as follows :
LS_COLORS="`echo $LS_COLORS |sed ’s/di=[0-9]*;[0-9]*/di=01;34/; s/ow=[0-9]*;[0-9]*/ow=01;34/’`”
export LS_COLORS
Regards
You don’t make any mention of ~/.dir_colors or /etc/DIR_COLORS. At least the link provided by MightyBigCar does so, (and there is one in a comment)/ It seems to me that ~/.dir_colors is a convenient place to define colors.
Otherwise, a very useful tutorial.
thanks.
Thanks j tweed, you are right. I have added a section describing the dir_colors file.
Seems like it boils down to this:
1. dircolors –print-database > ~/.dircolors
2. vi .dircolors
3. update bashrc to look for ~/.dircolors (as per info page referenced in “man dircolors")
if [ -x /usr/bin/dircolors ]; then
d=.dircolors
test -r $d && eval “$(dircolors $d)” || eval “`dircolors -b`”
Thanks for all the info.
This was very useful to me cos my old eyes don’t like DIR 1;034 which is the bold blue used by default for directories on my Ubuntu 8.04 Hardy set up. I changed it to bold yellow so now I can see it. Who chooses these things anyway? Thank you!
I work in an environment where a bunch of users are idiots and make everything 777 or 755. Is there a way to make is so that ex= does not override extensions like *.gz?
Love the article, but I do have one question. This seems to work perfectly in OS X, but when I do the exact same thing in Kubuntu 10.04, the first line of the ls -la listing is bright in color, and all the others are colored, but dull. Any ideas?
I have recently switched from BSD ls to GNU ls, and have been trying to perfect my LS_COLORS — this guide has been a godsend (one of many)…
A couple of things - you are missing at least two key - mh/MULTIHARDLINK for “Regular file[s] with more than one link” and ca/CAPABILITY for “File with capability.”
Also, and I haven’t seen this anywhere, if you’re feeling bold you can use the 256 colors of xterm instead of ANSI colors. You want to set the value of the key to the whole xterm escape sequence, as in \033[38;5;159. 38 there refers to foreground, 48 would be background. 159 is the color. Colors can be separated w/ the letter ‘m’, and ANSI escapes for underline, bold, flash, etc. can also be tacked on with an ‘m,’ as in \033[38;5;159m\e[04 (same as above, only underlined.)
I dread that the above will get eaten in the commenting process… :)
change Black for Block in the table
bd BLOCK, BLK Black device
Is there a simple way to turn off colors? (so that you see white letters on a black background and black letters on a white background). Putty defaults to a black background and xterm defaults to a white background.
In my opinion, blue-on-black and green-on-white are both ugly. : -)
Ok. I see now. To turn off colors use the unalias command.
unalias ls ;
alias | egrep ls
alias l.=’ls -d .* –color=tty’
alias ll=’ls -l –color=tty’
alias ls=’ls –color=tty’
It is ok to create new aliases that are not spelled the same as the standard commands. But I feel very strongly that you should never change the behaviour of an existing command such as ls. The last thing you want is to have your script changing behaviour (breaking) based on the configuration of the user running it.
This is a great guide. Thanks for writing it.
Other than color names choice (ie 33 looks like yellow and 47 like white to me eyes), this is a fu*ing well done an dcomprehensive explanation on setting up LS_COLORS :)
Here’s how I set it up in ~/.bashrc (XDG compliant if it exists):
—
# Enable colors for ls, etc, prefering user’s dircolors
if type -P dircolors >/dev/null ; then
if [[ -f “$XDG_HOME_CONFIG/bash/dircolors” ]] ; then
eval $(dircolors -b “$XDG_HOME_CONFIG/bash/dircolors")
elif [[ -f ~/.dircolors ]] ; then
eval $(dircolors -b ~/.dircolors)
elif [[ -f /etc/DIR_COLORS ]] ;
then
eval $(dircolors -b /etc/DIR_COLORS)
fi
fi
—
The following article emphasize on testing colors (nice tests) and setting usefull prompts thanks to your colors: *Bash tips: Colors and formatting* ( http://misc.flogisoft.com/bash/tip_colors_and_formatting )
In Ubuntu 15.10 (and perhaps in the Debian it is derived from), the setup is already in place. You just have to create the desired color scheme in your home directory as ~/.dircolors. The other locations mentioned above are not supported out of the box. The relevant stanza in the provided .bashrc is (in part):
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)";
alias ls='ls --color=auto';
fi
Thank you for this.
I had a problem with a bright green highlight showing for the background color of directories on an NTFS drive. Changing the line in .dir_colors from:
OTHER_WRITABLE 34;42 # dir that …
to:
OTHER_WRITABLE 94;40 # dir …
made it more bearable.

