Probably the first command line tool I learned was ls.  It’s a simple tool that lists (hence the overly-abbreviated name) the contents of a directory.  I’ve often wondered about the color-coding that is built into ls.  I could tell that it had meaning, but I couldn’t find any sort of chart anywhere to tell me what the different color codes mean.  I asked a co-worker about it one day, and he knew the color codes and explained them to me, but the explanations didn’t stick.  When I went to research it later, I figured it was one of those things that unixy people just know, as I couln’t really find any information on it–not in any handy form, at least.

After digging around, I discovered a tool called dircolors.  I’m no expert on the ins and outs of dircolors, but I figured out that if I typed the command, then the terminal would spit out a flood of code that apparently shows the correlation between different file and directory types and how they get colored by ls.

The output looks like this:

LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.svgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:';
export LS_COLORS

Which didn’t help me as much as I wanted.  But it did provide the impetus to write a script to help me figure things out.  I wrote my first bash script ever yesterday, and I have been learning about sed and regular expressions.  So I figured I’d try writing a script that uses sed to turn the output of dircolors into something I can actually read.

I’m sure my script is horribly inelegant, but give me a break–it’s my second script ever. What’s important, though, is that I accomplished my goal: learning what the color-coded output of ls means.

In case you want to try it, here’s my script:

#! /bin/bash
## make a human-readable copy of the output of dircolors
#
## output to file
dircolors > dircolors.txt
#
## trim the extraneous data that doesn't related directly to the color settings
sed -i 's/LS_COLORS=.//' dircolors.txt
sed -i 's/.;$//' dircolors.txt
sed -i 's/export LS_COLORS//' dircolors.txt
sed -i 's/:/\n/g' dircolors.txt
#
## convert delimiters to tabs
sed -i 's/[=;]/\t/g' dircolors.txt
#
## convert number values to human-readable form
#
## attributes
sed -i 's/00/attribute-none/g' dircolors.txt
sed -i 's/01/attribute-bold/g' dircolors.txt
sed -i 's/04/attribute-underscore/g' dircolors.txt
sed -i 's/05/attribute-blink/g' dircolors.txt
sed -i 's/07/attribute-reverse/g' dircolors.txt
sed -i 's/08/attribute-concealed/g' dircolors.txt
## text color
sed -i 's/30/text-black/g' dircolors.txt
sed -i 's/31/text-red/g' dircolors.txt
sed -i 's/32/text-green/g' dircolors.txt
sed -i 's/33/text-yellow/g' dircolors.txt
sed -i 's/34/text-blue/g' dircolors.txt
sed -i 's/35/text-magenta/g' dircolors.txt
sed -i 's/36/text-cyan/g' dircolors.txt
sed -i 's/37/text-white/g' dircolors.txt
##
## background color
sed -i 's/40/background-black/g' dircolors.txt
sed -i 's/41/background-red/g' dircolors.txt
sed -i 's/42/background-green/g' dircolors.txt
sed -i 's/43/background-yellow/g' dircolors.txt
sed -i 's/44/background-blue/g' dircolors.txt
sed -i 's/45/background-magenta/g' dircolors.txt
sed -i 's/46/background-cyan/g' dircolors.txt
sed -i 's/47/background-white/g' dircolors.txt
## keys -- translating all those two-character codes
sed -i 's/^no/&\tNorm/g' dircolors.txt
sed -i 's/^fi/&\tFile/g' dircolors.txt
sed -i 's/^di/&\tDir /g' dircolors.txt
sed -i 's/^ln/&\tLink/g' dircolors.txt
sed -i 's/^pi/&\tPipe/g' dircolors.txt
sed -i 's/^do/&\tDoor/g' dircolors.txt
sed -i 's/^bd/&\tBlk /g' dircolors.txt
sed -i 's/^cd/&\tChar/g' dircolors.txt
sed -i 's/^or/&\tOrph/g' dircolors.txt
sed -i 's/^so/&\tSock/g' dircolors.txt
sed -i 's/^su/&\tSetUid/g' dircolors.txt
sed -i 's/^sg/&\tSetGid/g' dircolors.txt
sed -i 's/^tw/&\tStkW/g' dircolors.txt
sed -i 's/^ow/&\tOthW/g' dircolors.txt
sed -i 's/^st/&\tStky/g' dircolors.txt
sed -i 's/^ex/&\tExec/g' dircolors.txt
#
## output the file, replacing double linefeed with single linefeed
cat dircolors.txt | tr -s '\n' '\n'

You’ll notice by the last line that I didn’t use sed for the whole script. Apparently, sed can’t quite handle replacing newline breaks. I tried just using tr to replace the newline breaks within the dircolors.txt file, but it did really weird things. Apparently, I don’t know how to use tr, I guess, other than to pipe some cat to it in order to replace double newlines with a single newline.

The output of the script looks like this:

no Norm attribute-none
fi File attribute-none
di Dir attribute-bold text-blue
ln Link attribute-bold text-cyan
pi Pipe background-black text-yellow
so Sock attribute-bold text-magenta
do Door attribute-bold text-magenta
bd Blk background-black text-yellow attribute-bold
cd Char background-black text-yellow attribute-bold
or Orph background-black text-red attribute-bold
su SetUid text-white background-red
sg SetGid text-black background-yellow
tw StkW text-black background-green
ow OthW text-blue background-green
st Stky text-white background-blue
ex Exec attribute-bold text-green
*.tar attribute-bold text-red
*.tgz attribute-bold text-red
*.svgz attribute-bold text-red
*.arj attribute-bold text-red
*.taz attribute-bold text-red
*.lzh attribute-bold text-red
*.lzma attribute-bold text-red
*.zip attribute-bold text-red
*.z attribute-bold text-red
*.Z attribute-bold text-red
*.dz attribute-bold text-red
*.gz attribute-bold text-red
*.bz2 attribute-bold text-red
*.bz attribute-bold text-red
*.tbz2 attribute-bold text-red
*.tz attribute-bold text-red
*.deb attribute-bold text-red
*.rpm attribute-bold text-red
*.jar attribute-bold text-red
*.rar attribute-bold text-red
*.ace attribute-bold text-red
*.zoo attribute-bold text-red
*.cpio attribute-bold text-red
*.7z attribute-bold text-red
*.rz attribute-bold text-red
*.jpg attribute-bold text-magenta
*.jpeg attribute-bold text-magenta
*.gif attribute-bold text-magenta
*.bmp attribute-bold text-magenta
*.pbm attribute-bold text-magenta
*.pgm attribute-bold text-magenta
*.ppm attribute-bold text-magenta
*.tga attribute-bold text-magenta
*.xbm attribute-bold text-magenta
*.xpm attribute-bold text-magenta
*.tif attribute-bold text-magenta
*.tiff attribute-bold text-magenta
*.png attribute-bold text-magenta
*.svg attribute-bold text-magenta
*.mng attribute-bold text-magenta
*.pcx attribute-bold text-magenta
*.mov attribute-bold text-magenta
*.mpg attribute-bold text-magenta
*.mpeg attribute-bold text-magenta
*.m2v attribute-bold text-magenta
*.mkv attribute-bold text-magenta
*.ogm attribute-bold text-magenta
*.mp4 attribute-bold text-magenta
*.m4v attribute-bold text-magenta
*.mp4v attribute-bold text-magenta
*.vob attribute-bold text-magenta
*.qt attribute-bold text-magenta
*.nuv attribute-bold text-magenta
*.wmv attribute-bold text-magenta
*.asf attribute-bold text-magenta
*.rm attribute-bold text-magenta
*.rmvb attribute-bold text-magenta
*.flc attribute-bold text-magenta
*.avi attribute-bold text-magenta
*.fli attribute-bold text-magenta
*.gl attribute-bold text-magenta
*.dl attribute-bold text-magenta
*.xcf attribute-bold text-magenta
*.xwd attribute-bold text-magenta
*.yuv attribute-bold text-magenta
*.aac attribute-none text-cyan
*.au attribute-none text-cyan
*.flac attribute-none text-cyan
*.mid attribute-none text-cyan
*.midi attribute-none text-cyan
*.mka attribute-none text-cyan
*.mp3 attribute-none text-cyan
*.mpc attribute-none text-cyan
*.ogg attribute-none text-cyan
*.ra attribute-none text-cyan
*.wav attribute-none text-cyan

Now whenever I’ve got a question about what a color-code means in ls, I run my script and then pipe the dircolors.txt to a grep in order to look up a specific color. For example:

cat dircolors.txt | grep green

Which produces:

tw StkW text-black background-green
ow OthW text-blue background-green
ex Exec attribute-bold text-green

Now I can see that executables are bold and green. And those annoying blue text on green background folders are other writables — whatever that means.

In restrospect, I bet there’s a way I could pass a variable to the script so that it would output just what I’m looking for instead of having to run the script and then pipe the cat of the text file to grep.

PS:

My thanks to Mr N for his list of what all those little two-character file/directory types mean.

Also thanks to Linux Blog for the tutorial on removing new line characters with a variety of tools (tr, awk, perl, sed, C/C++)

Advertisements