Switching to zsh
I have never looked into using a different shell in Linux, I’m not entirely sure why, maybe I just liked bash enough. This past week I started looking into zsh, and liked what I saw. Last night I migrated my shell files to be 99.9% interchangeable between shells and continue to load what I want without me having to change anything.
This post outlines some changes I made that will allow me to use both bash and zsh with the same startup files, but still have some shell specific settings that will get sourced. I didn’t need to move the files to ~/.shellfiles, but I felt having all of them as symlinks instead of some being symlinks to other dotfiles. Some of the shell specific things are setopt/shopt commands, setting prompts, and history settings.
I am storing the files in ~/.shellfiles, it isn’t my preferred choice, but it is less likely to be used by something else. Since I use version control on my home directory I needed to first ‘hg rename’ each one of my files to the ~/.shellfiles directory. After moving the files symlinks needed to be created to the original files.
.bash_logout -> .shellfiles/logout
.bash_profile -> .shellfiles/profile
.bashrc -> .shellfiles/rc-shell
.profile -> .shellfiles/profile
.zlogout -> .shellfiles/logout
.zprofile -> .shellfiles/profile
.zshenv -> .shellfiles/env
.zshrc -> .shellfiles/rc-shell
Inside of ~/.shellfiles/profile two variables are set and two log entries are added to ~/.shellfiles/shell_history, which I added as a log of when shells are exec’d, what files are sourced, and the order they are sourced. The following shows what happens when I login, open a shell, do some work, and then switch from zsh to bash.
################################# LOGIN ########################################
02/20/10 10:19:12
.shellfiles/profile
02/20/10 10:19:12
.shellfiles/rc-shell
.shellfiles/rc-zsh
.shellfiles/completion-zsh
.shellfiles/functions
.shellfiles/aliases
02/20/10 10:19:36
.shellfiles/env
02/20/10 10:19:36
.shellfiles/rc-shell
.shellfiles/rc-zsh
.shellfiles/completion-zsh
.shellfiles/functions
.shellfiles/aliases
02/20/10 10:19:41
.shellfiles/rc-shell
.shellfiles/rc-bash
.shellfiles/completion-bash
.shellfiles/functions
.shellfiles/aliases
From time to time I need to refresh a file like my aliases or functions so I created a function, ‘refresh’, that I can run to source files and take into account dependencies and add the log entry for that file. So that if I run ‘refresh aliases’, I would have a history entry like this.
02/20/10 10:47:30
.shellfiles/aliases
I’ll admit the shell history might be a bit overboard, but I needed to implement it when I was initially splitting up files so that I could ensure the correct files were sourced in various situations.
Within ~/.shellfiles/rc-shell I have a section at the top that sources shell specific files, and below that it has shared exports, sourced files, and operations.
if [ -z "$ZSH_VERSION" ] && [ -z "$BASH_VERSION" ]; then
CUR_SHELL=$(echo $SHELL | awk -F'/' '{print $NF}')
elif [ -n "$BASH_VERSION" ]; then
CUR_SHELL='bash'
elif [ -n "$ZSH_VERSION" ]; then
CUR_SHELL='zsh'
else
CUR_SHELL='bash'
fi
printf "\n$(date +"%D %T") \n .shellfiles/rc-shell\n" >> $SHELLHISTORY
if [ -f "$SHELLFILES/rc-$CUR_SHELL" ]; then
. "$SHELLFILES/rc-$CUR_SHELL"
fi
#------------------------------------------------------------------------------#
# Shared between zsh and bash
if [ -f "$SHELLFILES/functions" ]; then
. "$SHELLFILES/functions"
fi
.....
When a user is logging into the system the actual version of the shell is not available, so you need to base the startup files on the user’s shell. Within a console or within a script the versions are available, so if when you open a terminal it will determine if it is bash or zsh based on checking if the version variable for each shell has a value greater than 0. Once the it is known what shell we are in the proper files will be sourced.
