In preparation from my migration to Catalina this weekend, I put together a quick list of changes to keep in mind when using Bash over Zsh. Keep in mind that a modern build of Bash has most of these features but I’ll always jump at the opportunity to learn something new.
Here’s my humble original bashrc file (GitHub).
source $HOME/.aliases
# Read our local bashrc.
source $HOME/.bashrc_local
# Set environmental variables.
EDITOR=vim
# Turn off system bell if we're not in an SSH session.
if [ -z ${SSH_TTY+x} ]; then
if [ -z ${DISPLAY+x} ]; then
command -v setterm
if [ $? -eq 0 ]; then
setterm --blength 0
fi
else xset -b
fi
fi
# Create the prompt.
BLUE="\[\e[0;34m\]"
OFF="\[\033[m\]"
PS1="$%{BLUE%} $ $%{OFF%}"
This file also turns off the system bell – very useful for new machines or virtual machines. .bashrc_local
isn’t checked in version control. It contains the emoji for the specific machine. In the case of Apple it’s just: ‘EMOJI=’.
Based on stepping through a lot of ZSH configs (see footer) here’s my changes.
Migrating existing bash config to zsh
To prepare myself for the migration I spent an hour or so reading man zshmisc
. First I copied my bashrc into a new file named ~/.zshrc. Then, because the colour escape sequences weren’t working, I updated the BLUE and OFF lines to be compatible.
To test colours, I made heavy use of print -P '<escape sequence>'
and wrapping the colours in %{...%}
.
- BLUE=”%F{blue}”
- OFF=”%f”
- PROMPT=”\$”
- PS1=”${EMOJI} %{${BLUE}%}${PROMPT}${OFF} “
As my original config was very simple, this was enough.
Taking advantage of ZSH functionality
Now zsh has alot of built in functionality that I was reluctant to take advantage of for compatibility reasons — however, I spend a lot of time in the terminal so I found this few changes a good compromise between a supercharged terminal and a minimalist configuration.
Start by reading man zshbuiltins
.
Options
Configure options by running setopt OPTIONNAME and setopt noOPTIONNAME to unset. http://zsh.sourceforge.net/Doc/Release/Options.html#Options
AUTO_CD
Automatically move into a new directory if only that name is typed at the prompt.
$ pwd
$ /home/local
$ bin
$ pwd
$ /home/local/bin
APPEND_HISTORY
All zsh sessions append their command history to a single file instead of replacing it. Note that the history file isn’t updated until that zsh instance exits.
EXTENDED_HISTORY
Also save the command’s timestamp and duration in the history file. Extremely useful for timing commands.
HISTNOSTORE
Don’t store invocations of the builtin history
in the history file.
Functions
Completion system
I opted to start using the autocompletion system for smarter tab completion.
$ ls -<TAB>
-1 -- single column output
-A -- list all except . and ..
-B -- print octal escapes for control characters
-C -- list entries in columns sorted vertically
[.. snip ..]
Modules
zsh includes a lot of built-in modules to further change the behaviour of the shell. I didn’t opt to enable them in my config.
Final configuration
Here’s my final zsh config with all the above taken into account. I imagine 3 months down the road this file will have even more changes. You can always check the latest in xocite/dotrc/.zshrc @ GitHub.
# Read our aliases file.
source $HOME/.aliases
# Read our local zshrc.
source $HOME/.zshrc_local
# Set environmental variables.
EDITOR=vim
# Turn off system bell if we're not in an SSH session.
if [ -z ${SSH_TTY+x} ]; then
if [ -z ${DISPLAY+x} ]; then
command -v setterm
if [ $? -eq 0 ]; then
setterm --blength 0
fi
else xset -b
fi
fi
# Set options
setopt AUTO_CD
setopt APPEND_HISTORY
setopt EXTENDED_HISTORY
setopt HIST_NO_STORE
# Load functions
autoload -U compinit && compinit
# Create the prompt.
BLUE="%F{blue}"
OFF="%f"
PROMPT="\$"
PS1="${EMOJI} %{${BLUE}%}${PROMPT}${OFF} "