I tried out zsh, but it had too many buggy display bits for my tastes. After spending too much time researching the issues zsh and I called it quits for now.
I’ve stuck with bash and build a fairly solid config that works for the way I work.
A great book for learning bash is the O’Reily Learning the bash shell
FILES
       /bin/bash
           The bash executable
       /etc/profile
           The systemwide initialization file, executed for login shells
       ~/.bash_profile
           The personal initialization file, executed for login shells
       ~/.bashrc
           The individual per-interactive-shell startup file
       ~/.bash_logout
           The individual login shell cleanup file, executed when a login shell exits
       ~/.inputrc
           Individual readline initialization file
{{more}}
.bashrc
Historical Matching
This is one of my favorites:
if [[ $- == *i* ]]
then
  bind '"\e[A": history-search-backward'
  bind '"\e[B": history-search-forward'
fi
      
It matches what you’ve typed in the shell with historical lines.
example:
$ sudo nmap <Up arrow ↑> 
results in 
$ sudo nmap -p22 -Pn 192.168.1.1-254 | grep -B5 Raspberry
.bash_profile
.aliases
Keep the local stuff in ~/.aliases for a machine
See also
I’ve been playing around with a script that replaces all of the . files with files stored in a git repo.
Super handy for deploying new personal systems.
dotfiles forked from michaeljsmalley (His repos do not seem to exist any longer.)
Example
##############################################################################
# 01. Shell
##############################################################################
function __setprompt
{    
    export PS1="\e[0;32m[\u@\h \W]\$ \e[0m"
}
PROMPT_COMMAND='__setprompt'
##############################################################################
# 02. History
##############################################################################
if [[ $- == *i* ]]
then
  bind '"\e[A": history-search-backward'
  bind '"\e[B": history-search-forward'
fi
#HISTTIMEFORMAT='%F %T '
HISTFILESIZE=-1
HISTSIZE=-1
#Ignore duplicates in file and items starting with a space
HISTCONTROL=ignoredups:ignorespace
HISTIGNORE=?:??
shopt -s histappend                 # append to history, don't overwrite it
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
# attempt to save all lines of a multiple-line command in the same history entry
shopt -s cmdhist
# save multi-line commands to the history with embedded newlines
shopt -s lithist
##############################################################################
# 03. Aliases                                                                #
##############################################################################
# Enable colors in "ls" command output
alias ls='ls --color=auto'
alias dir='dir --color=auto'
alias grep='grep --color=auto'
# Global Aliases
alias historyg='history | grep $1'
alias hg='history | grep $1'
alias h='history'
alias gaacp='git add . && git commit && git push'
# Change directory aliases
alias home='cd ~'
alias cd..='cd ..'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
# Copy and go to the directory
cpg ()
{
        if [ -d "$2" ];then
                cp $1 $2 && cd $2
        else
                cp $1 $2
        fi
}
# Move and go to the directory
mvg ()
{
        if [ -d "$2" ];then
                mv $1 $2 && cd $2
        else
                mv $1 $2
        fi
}
#mkdir and cd to the new dir
mkdirg ()
{
        mkdir -p $1
        cd $1
}
# Local Aliases in Aliases file:
source $HOME/.aliases
##############################################################################
# 04. Theme/Colors                                                           #
##############################################################################
# CLI Colors
export CLICOLOR=1
export TERM="xterm-256color"
# Set "ls" colors
export LSCOLORS=Gxfxcxdxbxegedabagacad
##############################################################################
# 05. Paths
##############################################################################
#export PATH=.bash.paths