FreeBSD is Fun

Practical recipes for FreeBSD

Coloring your shell

Posted

by

Category

Introduction

If you are like me and enjoy spending time fiddling with FreeBSD, or you want to make it a bit harder to avoid making mistakes because you edited the wrong file or something, it pays off to set up some coloring in your FreeBSD shell. Not for the aesthetics, but to identify easier: who we are (user), where we are (path), and what are we looking at (file coloring)

First let’s start with the subject of shells. Zsh is pretty popular among programmers, and it also provides an easy way to do exactly what we want through the Oh My Zsh addon. Oh My Zsh is a package designed to make zsh easier to use; you can head here for more details if you want to know more:

https://github.com/ohmyzsh/ohmyzsh

Note that you can also use zsh as a root shell if you wish, but any Unix admin worth his salt will tell you, the root user should be using one of the default shells available with FreeBSD, since, if you run into any issue while configuring or installing zsh you won’t be able to su to root, which is an awkward situation to find yourself in. So I will explain how to do create the same color scheme with FreeBSD’s default shell, csh.

Now for the sake of example, let’s say we have two users to deal with: root, and the user for our hypotetical game server which is aptly called game.

2. Installing Zsh

So let’s login as root and install both git and the zsh shell binary. We can do it from packages or ports, just stick to one method or you will break dependencies and other nasty stuff.

pkg update
pkg install git zsh

Or for ports. You may get questions, just press enter if unsure and hope for the best.

portsnap auto
cd /usr/ports/devel/git
make install clean
cd /usr/ports/shells/zsh
make install clean

Now let’s create our unprivileged user if we don’t have one yet:

adduser game

We wil get a bunch of questions, just leave defaults as they are – except for two things; the shell which will be /usr/local/bin/zsh, and when asked “Invite to other groups?” you should type wheel. Adding a user to the wheel group allows us to switch back to the root account through the su command.

And of course you may want to type a password, though I prefer using ssh keys for login myself and disabling ssh password authentication altogether.

That was easy wasn’t it?

3. Installing oh-my-zsh

Now let’s switch to our new user with:

su game

Note: Something that annoys me is how the numeric keypad doesn’t work out of the box in zsh, specifically the / * – symbols which I use all the time. To amend this, you can add the key bindings in this post in the /home/<user>/.zshrc file. Note these may differ depending on your keyboard – assuming you use putty, you can press ctrl+v and then the desired key to find out the proper code to use for that specific key:

https://superuser.com/questions/742171/zsh-z-shell-numpad-numlock-doesnt-work

Make sure we are at the home directory (/home/game) and then proceed to install Oh My Zsh:

fetch https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
sh install.sh

Yes we can install oh-my-zsh even though we are not the root user; of course it will work only for this user.

Now try logging in a second Putty window to make sure everything works as intended – it’s a good practice when we are changing stuff like shells, ssh or firewall parameters, to make sure we don’t get locked out of our own system.

4. Setting up an oh-my-zsh theme

Once installed, you can change the zsh theme to any of the ones available under the.oh-my-zsh/themes/ directory, or even create your own. Be aware though that the FreeBSD terminal only supports 16 colors by default, so all those fancy Linux ones won’t work properly without heavy modification of the environment.

https://github.com/ohmyzsh/ohmyzsh/wiki/Themes

Luckily for you I provide here my own color scheme perfectly adapted for this amazing operating system, in case you want to use it – just create a new file called .oh-my-zsh/themes/wom.zsh-theme  -mind the dot before oh- and paste the text on it.

Now just save it and then set the theme as “wom” at the beginning of the .zshrc file. Mind the dot at the start of the filename, which is Unix’s way of keeping a file hidden.

if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="white"; fi

PROMPT='%{$fg[$NCOLOR]%}%B%n@%m%b%{$reset_color%}:%{$fg[blue]%}%B%0d%b%{$reset_color%} $(git_prompt_info)%(!.#.$) '
RPROMPT='[%*]'

# git theming
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}(%{$fg_no_bold[yellow]%}%B"
ZSH_THEME_GIT_PROMPT_SUFFIX="%b%{$fg_bold[blue]%})%{$reset_color%} "
ZSH_THEME_GIT_PROMPT_CLEAN=""
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}✗"

# LS colors, made with https://geoff.greer.fm/lscolors/
export LSCOLORS="Gxfxcxbxdxegedabagacad"
export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'

Once you are done you can either open a new ssh session or just switch to root and then back:

$ su
Password:
root@nginx:/home/www # su webmaster
webmaster@nginx:/home/www $ 

Play around with the ls and cd commands to check directory listing and autocompletion are properly colorized.

If you want to make your own theme, you can replace the parameters of the PROMPT (self explanatory), LSCOLORS (directory listing) and list-colors (autocomplete) – for the later two you can get the appropiate strings here:

https://geoff.greer.fm/lscolors/

Note that the brownish color in this tool is actually yellow in FreeBSD, and that to access the second set of 8 colors you should mark “bold” which is not really bold but a different shade of the same color (?)

5. Shell coloring in csh

Okay time to move to the root user and its default system shell which is a bit less user friendly.

You can edit the /root/.cshrc file to change the root user preferences like this:

setenv  LSCOLORS        ExGxfxcxBxegehbhbgacad
setenv  LS_COLORS       "di=1;34:ln=1;36:so=35:pi=32:ex=31:bd=34;46:cd=34;47:su=31;47:sg=31;46:tw=30;42:ow=30;43"

set     red="%{\033[1;31m%}"
set   green="%{\033[1;32m%}"
set  yellow="%{\033[1;33m%}"
set    blue="%{\033[1;34m%}"
set magenta="%{\033[1;35m%}"
set    cyan="%{\033[1;36m%}"
set   white="%{\033[0;37m%}"

set     end="%{\033[0m%}" # This is needed at the end of the prompt

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set prompt = "${red}%N@%m:${green}%~ ${white}%#${end} "
        set promptchars = "%#"

        set filec
        set history = 1000
        set savehist = (1000 merge)
        set autolist = ambiguous
        # Use history to aid expansion
        set autoexpand
        set autorehash
        set mail = (/var/mail/$USER)
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
        endif

endif

# Clean up after ourselves...
unset red green yellow blue magenta cyan yellow white end

These settings will result in exactly the same coloring as in my wom theme for oh-myzsh; besides I also set ee as the default editor and less as the default pager. Feel free to change these to your liking.

For those curious about the topic I will explain the parts of this file related to coloring, since documentation on the net is pretty sparse about this:

setenv LSCOLORS will define the colors for directory listing (ls) – note that for this to work ls needs to be invoked with either the -G or the -l parameter, that’s why we add the alias ls ls -G line. The parameters defining colors here are the same as in zsh.

setenv LS_COLORS defines the color scheme for the autocomplete, just like list-colors did in oh-my-zsh. Once again, it works the same way parameter wise. Interestingly, this parameter is used for directory listings in bash, hence the confusing naming of the variables.

The set red, green, etc lines are just a helper for coloring the prompt later on the script here: 

set prompt = "${red}%N@%m:${green}%~${white} %# ${end}"

6. Notes

What if we want to use zsh and oh-my-zsh for all the users including root?

In that case you should not install it from the unprivileged user but from root.

And what if we want to install oh-my-zsh for several unprivileged users, leaving root with csh?

You will notice that if you try to install oh-my-zsh a second time, you will get an error. The way around this is, assuming we are logged in as this other user (let’s call it “www”) and in its home directory – let’s call it /home/www:

rm .zshrc*
unset ZSH

Now you can follow the same steps listed earlier to install it for this user.

7. TL; DR

If you want to get a preview of how this stuff looks like, just copy and paste this on your putty window while you are logged in to a shell:

echo 'set color' >> ~/.cshrc
echo 'alias ls ls -G' >> ~/.cshrc

(Final thanks to Tim Niederhausen to introducing me to the topic and FreeBSD in general.)

Not feeling confident? You can always hire me to perform this or any other of the administrative tasks described in this blog.


Leave a Reply

Your email address will not be published. Required fields are marked *