How to Change Default Shell from sh to zsh/bash in FreeBSD System-wide


2 views

FreeBSD comes with /bin/sh (the Almquist shell) as default, which lacks many modern features that power users expect:

  • Basic tab completion
  • Command history navigation
  • Advanced scripting capabilities
  • Custom prompt configuration

First, install your preferred shell from packages:

# For zsh:
pkg install zsh

# For bash:
pkg install bash

Edit /etc/shells to add your new shell (required for chsh):

# echo "/usr/local/bin/zsh" >> /etc/shells
# echo "/usr/local/bin/bash" >> /etc/shells

Modify /etc/master.passwd to set the default shell for new users:

# vipw
# Change the default shell line from:
defaultshell=/bin/sh
# To:
defaultshell=/usr/local/bin/zsh

Then rebuild the password database:

# pwd_mkdb -p /etc/master.passwd

For current users (including root), use chsh:

# chsh -s /usr/local/bin/zsh username
# chsh -s /usr/local/bin/zsh root

Edit /etc/adduser.conf to set the default shell for new accounts:

defaultshell=/usr/local/bin/zsh

Check the current shell for any user:

# grep ^username /etc/passwd

For immediate effect without relogin:

exec /usr/local/bin/zsh

Consider these popular configuration frameworks:

  • For zsh: oh-my-zsh or prezto
  • For bash: bash-it or liquidprompt
# Install oh-my-zsh
pkg install curl git
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

When working with FreeBSD systems, many developers find the default sh (Bourne shell) frustratingly limited. The missing features hurt productivity:

  • No advanced tab completion like in zsh/bash
  • Lack of command history shortcuts (!!, !$)
  • No syntax highlighting or intelligent suggestions
  • Primitive scripting capabilities compared to modern shells

First, ensure your desired shell is available through packages:

# For zsh:
pkg install zsh

# For bash:
pkg install bash

To change the default shell for all users (including future ones), modify /etc/defaults/rc.conf:

sysutils{
    default_shell="/usr/local/bin/zsh" # or /usr/local/bin/bash
}

For current users including root, use chsh:

# For root:
chsh -s /usr/local/bin/zsh root

# For regular users (replace username):
chsh -s /usr/local/bin/zsh username

Edit /etc/adduser.conf to set the default shell for future user creations:

defaultshell=/usr/local/bin/zsh

Create a test user to confirm the new defaults work:

pw useradd testuser -m
grep testuser /etc/passwd

The output should show your chosen shell path.

For zsh users, consider adding to /etc/zsh/zshenv:

autoload -U compinit
compinit
setopt autocd
setopt extendedglob

For bash users, add to /etc/bash.bashrc:

shopt -s cdspell
shopt -s checkwinsize
complete -cf sudo

If shells don't load properly, check:

  1. The shell binary exists at the specified path
  2. The shell is listed in /etc/shells
  3. No SELinux/AppArmor restrictions (uncommon on FreeBSD)