A Better Ls for Mac OS X

I’m a bit of a command-line freak and like to spend a fair amount of time with the terminal open… As such I like to spend a small amount of time getting the terminal set-up nicely. Other than changing the default colour scheme and font, one (slightly) more drastic change is to replace the standard implementation of ls for one that is slightly more configurable.

The default ls on OS X comes from BSD and compared to the GNU/Linux alternative is slightly lacking when it comes to comes to changing how things look - so what I like to do is replace it with the GNU ls available in MacPorts - this allows me to get a terminal setup like below:

terminal.png

To get this done is pretty simple, once you have MacPorts set up correctly (if you can type man port and get a manual page you’re ready), just run the following command:

sudo port install coreutils +with_default_names

This installs the ‘GNU File, Shell, and Text utilities’ which ls is part of - the extra option at the end +with_default_names makes it override (only override - not replace, this is totally removable) the default ls and other tools otherwise they will have a ‘g’ prefix - i.e. ls would be gls.

Next we add some extra configuration to our ~/.bash_profile file (i’ll include my MacPorts config in case you get stuck above)…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# MacPorts
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
export MANPATH=/opt/local/share/man:$MANPATH
 
# Terminal colours (after installing GNU coreutils)
NM="\[\033[0;38m\]" #means no background and white lines
HI="\[\033[0;37m\]" #change this for letter colors
HII="\[\033[0;31m\]" #change this for letter colors
SI="\[\033[0;33m\]" #this is for the current directory
IN="\[\033[0m\]"
 
export PS1="$NM[ $HI\u $HII\h $SI\w$NM ] $IN"
 
if [ "$TERM" != "dumb" ]; then
    export LS_OPTIONS='--color=auto'
    eval `dircolors ~/.dir_colors`
fi
 
# Useful aliases
alias ls='ls $LS_OPTIONS -hF'
alias ll='ls $LS_OPTIONS -lhF'
alias l='ls $LS_OPTIONS -lAhF'
alias cd..="cd .."
alias c="clear"
alias e="exit"
alias ssh="ssh -X"
alias ..="cd .."

Then finally we need to create a file called .dir_colors in our home directory that allows us to configure the colours used by ls:

touch ~/.dir_colors

Then add the contents of the file here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Configuration file for dircolors, a utility to help you set the
# LS_COLORS environment variable used by GNU ls with the --color option.
 
# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
# slackware version of dircolors) are recognized but ignored.
 
# Below, there should be one TERM entry for each termtype that is colorizable
TERM linux
TERM linux-c
TERM mach-color
TERM console
TERM con132x25
TERM con132x30
TERM con132x43
TERM con132x60
TERM con80x25
TERM con80x28
TERM con80x30
TERM con80x43
TERM con80x50
TERM con80x60
TERM xterm
TERM xterm-color
TERM xterm-debian
TERM rxvt
TERM screen
TERM screen-w
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;36 	# directory
LINK 01;37 	# symbolic link.  (If you set this to 'target' instead of a
           	# numerical value, the color is as for the file pointed to.)
FIFO 40;33	# pipe
SOCK 01;35	# socket
DOOR 01;35	# door
BLK 40;33;01	# block device driver
CHR 40;33;01 	# character device driver
ORPHAN 40;31;01 # symlink to nonexistent file
 
# This is for files with execute permission:
EXEC 01;35
 
# 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 '#')
 
# If you use DOS-style suffixes, you may want to uncomment the following:
#.cmd 01;32 # executables (bright green)
#.exe 01;32
#.com 01;32
#.btm 01;32
#.bat 01;32
 
.tar 01;31 # archives or compressed (bright red)
.tgz 01;31
.arj 01;31
.taz 01;31
.lzh 01;31
.zip 01;31
.z   01;31
.Z   01;31
.gz  01;31
.bz2 01;31
.deb 01;31
.rpm 01;31
.jar 01;31
.dmg 01;31
 
# image formats
.jpg 01;35
.png 01;35
.gif 01;35
.bmp 01;35
.ppm 01;35
.tga 01;35
.xbm 01;35
.xpm 01;35
.tif 01;35
.png 01;35
.mpg 01;35
.avi 01;35
.fli 01;35
.gl 01;35
.dl 01;35
 
# source code files
.pl 00;33
.PL 00;33
.pm 00;33
.tt 00;33
.yml 00;33
.sql 00;33
.html 00;33
.css 00;33
.js 00;33

Finally, all you need to do is close and re-open the Terminal. Now we should be sorted. :)

18 Responses to “A Better Ls for Mac OS X”


  1. 1 reuben cummings

    Thanks! this worked perfectly. One question though… how do I change the terminal so that the computer name is preceded by an “@” and the shell ends with a “$”? In otherwords, I want to change it from

    [ user macbook ~ ]

    to

    [ user@macbook ~ ]$

  2. 2 Daz

    Hi Reuben,

    To change that, simply replace the ‘export PS1’ line in .bash_profile with the following:

    export PS1="$NM[ $HI\u@$HII\h $SI\w$NM ]$ $IN"

    That should get you the result you’re after.

  3. 3 Matt

    Wow, worked like a charm! No more boring Terminals, thank you so much!

  4. 4 Paul

    I didn’t realise I could use of the tools in macports, thanks!

  5. 5 Ian

    I didn’t have a .bash_profile file, so I created one with the text above. Now when I log in, I get:

    -bash: dircolors: command not found
    [ Me Macintosh ~ ] ls
    ls: illegal option — -
    usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1] [file …]

    What did I do wrong?

  6. 6 Daz

    I didn’t have a .bash_profile file, so I created one with the text above. Now when I log in, I get:

    -bash: dircolors: command not found
    [ Me Macintosh ~ ] ls
    ls: illegal option — -
    usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1] [file …]

    What did I do wrong?

    It sounds like you haven’t got GNU ls installed properly. Did you install it via the MacPorts command listed above?

  7. 7 Ed Ruder

    Hmm. I’m getting a colorized shell prompt, but directory listings are still boring. Looking at ‘env’, all of the variables look reasonable (LS_COLORS set to a long string, LS_OPTIONS set to ‘—color=auto’, TERM is ‘xterm-color’). ‘which ls’ finds the one in ‘/opt/local/bin’, which is right.

    I’m running OS X 10.5.4. Any guesses what is going wrong?

  8. 8 Daz

    By still boring, do you mean that the directories are just plain blue?

    If they’re blue - things are working, if you want to play with the colours just edit the .dir_colors file to get something more to your tastes.

    If the directories are still green somethings gone wrong there…

  9. 9 Darren

    By still boring, do you mean that the directories are just plain blue?

    If they’re blue - things are working, if you want to play with the colours just edit the .dir_colors file to get something more to your tastes.

    If the directories are still green somethings gone wrong there…

    I have the same experience on Leopard (10.5.4) using Terminal with xterm-color and bash:

    [ dweber melovg5 ~ ] bash --version
    GNU bash, version 3.2.17(1)-release (powerpc-apple-darwin9.0)

    All entries in the directory listing are green text. How do these .dir_colors settings interact with the terminal preference settings?

  10. 10 Daz

    > [ dweber melovg5 ~ ] bash --version
    GNU bash, version 3.2.17(1)-release (powerpc-apple-darwin9.0)

    Have you got the MacPorts version of ls installed and in use? Try the following:

    ls --version

    It should give you ls (GNU coreutils) 6.9, if you get the following:

    ls: illegal option -- -
    usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1] [file ...]

    then the MacPorts version of ls is not in use… Make sure you have installed it, then add the following to the top of your .bash_profile file:

    # MacPorts
    export PATH=/opt/local/bin:/opt/local/sbin:$PATH
    export MANPATH=/opt/local/share/man:$MANPATH

    then quit Terminal and start it up again - see how that goes.

    > How do these .dir_colors settings interact with the terminal preference settings?

    The terminal preference settings only affects the base colour of the text - in my screen shot, green on a black background. The .dir_colors file is used to manipulate the colour of files/folders depending on what they are.

  11. 11 Nigel Green

    Many thanks for this article - just what I needed! I had some trouble getting anything other than plain white text at first, but the answer for me was an extra semi-colon in the color refs (so DIR 0136 becomes DIR 01;36 for example). Thanks also to dotfiles.org for providing other peoples config files to crib from…

  12. 12 Ed Ruder

    @Nigel: Your solution was the solution to my problem on OS X Leopard! Thanks very much, Daz!

  13. 13 Pseudo-Morph

    Daz, thanks very much. I have just got this working on my Macbook.

    For those that are interested I used fink to install the package ‘coreutils-default’ which is pretty much the same package from what I can tell.

    The one difference I discovered using fink is the path variable within the .bash_profile. While you could just change this to read ‘export PATH=/sw/bin:/sw/sbin:$PATH’ fink also comes with a binary file (init.sh for Bash or init.csh for tcsh) that exports your path for you.

    In this instance I added the line ‘. /sw/bin/init.sh’ to my .bash_profile. If you are using tcsh you will need to add the line ‘source /sw/bin/init.csh’ to your relevevent config file.

    Now if only I could change that gawdy blue used for folders to something readable…

  14. 14 Pseudo-Morph

    Ok, so I speak too soon. Any idea why the prompt colours work but none of the other file associations work?

    Adding a semi-colon to line 40 of .dir_colors as suggested above works to colour directories however results in the error ‘dircolors: /Users/pseudomorph/.dir_colors:40: invalid line; missing second token’.

    This approach does not seem to work for other file associations. Any clues welcome.

  15. 15 Pseudo-Morph

    Ok, ignore me. It helps if you look *really* closely at what you’re doing. Nigel’s approach did work when I implemented it correctly.

    I am now one very happy camper.

  16. 16 robbie

    thanks a lot of the guide, i’ve got it working except for one thing. my folders/files with full permission are shown with a blue text on green 34;42 which i do not have listed in the dir_colors from your site. I can hardly read the folder names and want to get rid of it .. is there another setting that is over riding the ones from here?

    any help would be greatly welcomed.

  17. 17 Elfar

    Works like a charm, thanks

  18. 18 Amish

    Hi,

    may be this is not the right place to ask, but is there a way to remove the “last login and so on…” string that appears everytime Terminal is opened? I’d like a clean prompt.

    Kind regards

    Amish

Leave a Reply