• Bash used to be the default shell in macOS
  • Zsh has been many developers’ favourite alternative
  • I’ve been happy enough with Bash, but ready to level up 🚀

It’s been 928 days since my notes to figure out wtf is bash anyway?! — and it’s time to move on.

The internet is helpful 🔗

Silence the warning 🤫

With macOS Catalina the default shell was changed to Zsh. When I was setting up an new work laptop last November, I was in no way ready to deal with changing all things shell at the same time. But an account set up to use Bash would start getting a persistent and noisy deprecation warning:

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.

At the time, I put this in my .bash_profile to make the warning go away:

export BASH_SILENCE_DEPRECATION_WARNING=1

But today is the day we level up and change the shell. Soooo, how tf to do that?! 🤷🏻‍♀️

Configure account to now use zsh

Before I removed the silencing and got back the helpful deprecation warning… I was reading about how to change it in the GUI under System Preferences. There’s a hidden “advanced options” you can find with a control-click on user name. The article from Apple also attempts to describe how to do it from the command line, so I was doing a cat /etc/shells to understand what they meant with “one of the shell paths listed”. But anyway, the deprecation warning explained exactly what to run:

chsh -s /bin/zsh

But how to migrate existing bash stuff?! 🤔

.zprofile is equivalent to .bash_profile and runs at login, including over SSH
.zshrc is equivalent to .bashrc and runs for each new Terminal session

Ok!? Not sure this was the way to go, but I renamed these files like so:

mv .bashrc .zshrc
mv .bash_profile .zprofile

New shell is now spewing out these warnings:

/Users/x/.zshrc:6: command not found: shopt
WARNING: this script is deprecated, please see git-completion.zsh
\[\e[1;35m\]\u@\h\[\e[0m\] \[\e[1;34m\]\w\[\e[1;31m\]$(parse_git_branch)\[\033[00m\] $

Ha. I know what those 3 things are. And happy with past-me for writing comments:

shopt -s histappend
# add reference to git completion from xcode command line tools
[ -f /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash ] && . /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash
# make a useful promt with pretty colours
parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[\e[1;35m\]\u@\h\[\e[0m\] \[\e[1;34m\]\w\[\e[1;31m\]\$(parse_git_branch)\[\033[00m\] $ "

Hm. I’ll remove them and figure out how to set up something similar in zsh. All right, then the noise is gone. Let’s see what works and what doesn’t?!

Aliases still work…

That’s unexpected. Ah, I have this in my now named .zshrc and that apparently finds them:

# add reference to bash aliases
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

For now, I am deleting my .bash_aliases file completely, and copying the aliases I want to keep over to .zshrc. Also deleting .bash_history while I’m at it, though I have kept a copy as a txt file in case something useful resides in there.

A POSIX-compliant profile ?!

If you're using .profile, you can make zsh automatically read its settings by adding this command to .zprofile:

[[ -e ~/.profile ]] && emulate sh -c 'source ~/.profile'

Ok. Yes. I’ve got that file. But the only thing it contains is:

# set bin directory for cargo (package manager for Rust)
# in my PATH environment variable (auto by the rustup installer)
export PATH="$HOME/.cargo/bin:$PATH"

Not sure what to do about this. Checking the docs on Rust installation I see there’s mention about Configuring the PATH environment variable. Perhaps I can run some rustup install scripts to confgure the path correctly. Or I can just see if something breaks next week when developing.

Zsh todo

Making a list of what I’ve lost and/or intentionally removed:

  • promt
  • git completion
  • something with nvm bash_completion
  • how history works (there’s a new .zsh_history but it’s empty

There are also tokens and paths I want to check still works. I was a bit curious about setting up minimal configuration before going bananas with frameworks and plugins. Read about manually Adding Git Completion to Zsh but decided to proceed with choosing between:

Oh My Zsh or Prezto?

Oh-my-zsh has a much larger selection of themes and plugins, but Prezto’s tab completion is noticeably faster. If you have a plugin you’d really miss by switching to Prezto, I’d suggest sticking with oh-my-zsh. Otherwise, the speed increase is well worth the switch.

A Beautifully Productive Terminal Experience

While Prezto is obviously widely used and maintained, I’m going to go with the community and what I’d heard about before, and install Oh My Zsh.

         __                                     __
  ____  / /_     ____ ___  __  __   ____  _____/ /_
 / __ \/ __ \   / __ `__ \/ / / /  /_  / / ___/ __ \
/ /_/ / / / /  / / / / / / /_/ /    / /_(__  ) / / /
\____/_/ /_/  /_/ /_/ /_/\__, /    /___/____/_/ /_/
                        /____/                       ....is now installed!

Right, I now have files attempting to zsh config, so perhaps diving straight for the framework would have made more sense then renaming like I did. But anyway!

🥳

And now for plugins and themes bonanza…