Occasionally people ask me how I managed to get my shell to look like this:

I never wanted to tell people before though, it was a terrible mess of copied code with no commenting or proper line indentation. Eventually though, I figured I used Linux enough to tidy it up, add an auto-updater and even a list of options. For nearly two week straight I’ve been tweaking it, and today, I present to you this culmination of work:

##############################################################################
#                         Codefined's ~/.bashrc File                         #
##############################################################################

# A compiled list of commands to aid with everyday usage of bash.  Borrowed
# from many sources, including:
#   http://www.tldp.org/LDP/abs/html/sample-bashrc.html
#   http://ubuntuforums.org/showthread.php?t=679762

# Installation Instructions:
# 1. Download this file `wget codefined.xyz/bashrc.txt`
# 2. Merge/replace your bashrc file `mv this_file ~/.bashrc`
# 3. Add `. .bashrc` to your bash_profile file
#      `echo ". .bashrc" >> ~/.bash_profile`
# 4. Run either `. .bashrc` or restart the shell to see changes


# Command Reference:
# up <number> - Goes up a certain amount of directories
# extract <file> - Attempts to extract the file
# ff <string> - Finds a file by it's name
# maketar <dir> - Creates an archive (*.tar.gz) from given directory
# makezip <dir/file> - Creates a ZIP archive from a file or folder
# sanitize <dir/file> - Gives sane permissions to a file or folder
# my_ps - Lists your processes
# killps - Kills a process by name
# get_ip - Gets your current IP address
# host_information - Lists information about your host
# repeat <number> <command> - Repeats a command 'n' times
# ask - Prmopts the user whether to continue
# corename <file> - Get which process created a corefile

# Custom Aliases:
# ll - List all files in detail
# la - Show hidden files
# l - Shortcut to ls
# back - Go to previous directory
# apt-get - Aptitude
# logs - Watch the log file
# install/update/upgrade/purge - sudo aptitude <command>
# path - Pretty-print the current path
# libpath - Pretty-print the current library path
# please/redo - Runs the previous command as sudo
# .2/.3/.4/.5 - Equivalent of doing up <n>

##############################################################################
#                               User Settings                                #
##############################################################################

enable_colours=true
enable_aliases=true
enable_fancy_terminal=true
enable_background_commands=true
enable_utility_commands=true
enable_process_commands=true
enable_information_commands=true
enable_misc_commands=true
enable_programmable_completion=true

fix_common_typos=true
use_aptitude=true

##############################################################################
#                         Generic ~/.bashrc Settings                         #
##############################################################################

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# Update window size after each command
shopt -s checkwinsize

# Fix less to be able to use non-text files
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# Set "**" to match all files and zero or more subdirectories
# shopt -s globstar

# Set Nano to be the default editor
export EDITOR=nano

##############################################################################
#                          Command History Settings                          #
##############################################################################

# Ignore empty and duplicate history items
HISTCONTROL=ignoreboth

# Append instead of re-writing the history file
shopt -s histappend

# Maximum file size for hisory
HISTSIZE=10000
HISTFILESIZE=20000

# Change the date-format to be more readable
export HISTTIMEFORMAT="[%Y-%m-%d %T] "

# Exclude ls, bg, fg and exit commands from the history
export HISTIGNORE="&:ls:[bf]g:exit"

##############################################################################
#                             Colour Variables                               #
##############################################################################

if [ "$enable_colours" = true ] ; then
  # Normal Colors
  Black='\e[0;30m'        # Black
  Red='\e[0;31m'          # Red
  Green='\e[0;32m'        # Green
  Yellow='\e[0;33m'       # Yellow
  Blue='\e[0;34m'         # Blue
  Purple='\e[0;35m'       # Purple
  Cyan='\e[0;36m'         # Cyan
  White='\e[0;37m'        # White

  # Bold
  BBlack='\e[1;30m'       # Black
  BRed='\e[1;31m'         # Red
  BGreen='\e[1;32m'       # Green
  BYellow='\e[1;33m'      # Yellow
  BBlue='\e[1;34m'        # Blue
  BPurple='\e[1;35m'      # Purple
  BCyan='\e[1;36m'        # Cyan
  BWhite='\e[1;37m'       # White

  # Background
  On_Black='\e[40m'       # Black
  On_Red='\e[41m'         # Red
  On_Green='\e[42m'       # Green
  On_Yellow='\e[43m'      # Yellow
  On_Blue='\e[44m'        # Blue
  On_Purple='\e[45m'      # Purple
  On_Cyan='\e[46m'        # Cyan
  On_White='\e[47m'       # White

  NC="\e[m"               # Color Reset

  RESET="\[\017\]"
  NORMAL="\[\033[0m\]"
  WHITE="\[\033[37;1m\]"
  BLUE="\[\033[34;1m\]"
  RED="\[\033[31;1m\]"
  YELLOW="\[\033[33;1m\]"
  GREEN="\[\033[32;1m\]"
  SUCCESS="${GREEN}:)${NORMAL}"
  FAILURE="${RED}:(${NORMAL}"
fi

##############################################################################
#                           Fancy Terminal Prompt                            #
##############################################################################

if [ "$enable_fancy_terminal" = true ] ; then
  # Select Statement
  SELECT="if [ \$? = 0 ]; then echo \"${SUCCESS}\"; else echo \"${FAILURE}\"; fi"

  # Throw it all together 
  PS1="${RESET}${YELLOW}\h${NORMAL} ${BLUE}\w${NORMAL} \`${SELECT}\` ${YELLOW}>${NORMAL} "

  # Color for manpages
  export LESS_TERMCAP_mb=$'\E[01;31m'
  export LESS_TERMCAP_md=$'\E[01;31m'
  export LESS_TERMCAP_me=$'\E[0m'
  export LESS_TERMCAP_se=$'\E[0m'
  export LESS_TERMCAP_so=$'\E[01;44;33m'
  export LESS_TERMCAP_ue=$'\E[0m'
  export LESS_TERMCAP_us=$'\E[01;32m'
fi

##############################################################################
#                               Command Aliases                              #
##############################################################################

if [ "$enable_aliases" = true ] ; then
  # Make ls, dir, vdir and grep use colour if possible
  if [ -x /usr/bin/dircolors ]; then
      test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
      alias ls='ls --color=auto'
      alias dir='dir --color=auto'
      alias vdir='vdir --color=auto'

      alias grep='grep --color=auto'
      alias fgrep='fgrep --color=auto'
      alias egrep='egrep --color=auto'
  fi

  # Alias some common ls parameters to other commands
  alias ll='ls -alF'
  alias la='ls -A'
  alias l='ls -CF'

  # Add an "alert" alias for long running commands.  Use like so:
  #   sleep 10; alert
  alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

  # Go back to your previous directory
  alias back='cd "$OLDPWD"'

  # Watch logs
  alias logs="find /var/log -type f -exec file {} \; | grep 'text' | cut -d' ' -f1 | sed -e's/:$//g' | grep -v '[0-9]$' | xargs tail -f"

  if [ "$enable_aliases" = true ] ; then
    # Use Aptitude instead of Apt-get
    alias apt-get='aptitude'

    # Simplify Aptitude Commands
    alias install='sudo aptitude install'
    alias update='sudo aptitude update'
    alias upgrade='sudo aptitude upgrade'
    alias purge='sudo aptitude purge'
  fi

  # Prompt on (re)moving files and clobbering directories
  alias rm='rm -i'
  alias cp='cp -i'
  alias mv='mv -i'
  alias mkdir='mkdir -p'

  # Pretty-print some PATH variables
  alias path='echo -e ${PATH//:/\\n}'
  alias libpath='echo -e ${LD_LIBRARY_PATH//:/\\n}'

  if [ "$fix_common_typos" = true ] ; then
    # Fix common typos
    alias xs='cd'
    alias vf='cd'
    alias moer='more'
    alias moew='more'
    alias kk='ll'
  fi

  # Redo the previous command as sudo
  alias please="sudo !!"
  alias redo="sudo !!"

  # Alternative to "up"
  alias .2='cd ../../'                        # Go back 2 directory levels
  alias .3='cd ../../../'                     # Go back 3 directory levels
  alias .4='cd ../../../../'                  # Go back 4 directory levels
  alias .5='cd ../../../../../'               # Go back 5 directory levels
  alias .6='cd ../../../../../../'            # Go back 6 directory levels
fi

##############################################################################
#                         Run Commands in Background                         #
##############################################################################

if [ "$enable_background_commands" = true ] ; then
  function example_background() { 
    command example_background "$@" & 
  }
fi

##############################################################################
#                           Custom Utility Commands                          #
##############################################################################

if [ "$enable_utility_commands" = true ] ; then
  # Allow `up 4` instead of `cd ../../../..`
  function up () {
    local d=""
    limit=$1
    for ((i=1 ; i <= limit ; i++))
      do
        d=$d/..
      done
    d=$(echo $d | sed 's/^\///')
    if [ -z "$d" ]; then
      d=..
    fi
    cd $d
  }

  # Extract lots of files via one command
  function extract () {
  	if [ -f $1 ] ; then
  		case $1 in
  			*.tar.bz2)	tar xjf $1		;;
  			*.tar.gz)	tar xzf $1		;;
  			*.bz2)		bunzip2 $1		;;
  			*.rar)		rar x $1		;;
  			*.gz)		gunzip $1		;;
  			*.tar)		tar xf $1		;;
  			*.tbz2)		tar xjf $1		;;
  			*.tgz)		tar xzf $1		;;
  			*.zip)		unzip $1		;;
  			*.Z)		uncompress $1	;;
  			*)			echo "'$1' cannot be extracted via extract()" ;;
  		esac
  	else
  		echo "'$1' is not a valid file"
  	fi
  }

  # Find a file by it's name
  function ff() { 
    find . -type f -iname '*'"$*"'*' -ls ; 
  }

  # Creates an archive (*.tar.gz) from given directory.
  function maketar() { 
    tar cvzf "${1%%/}.tar.gz"  "${1%%/}/"; 
  }

  # Create a ZIP archive of a file or folder.
  function makezip() { 
    zip -r "${1%%/}.zip" "$1" ; 
  }

  # Make your directories and files access rights sane.
  function sanitize() { 
    chmod -R u=rwX,g=rX,o= "$@" ;
  }
fi

##############################################################################
#                           Custom Process Commands                          #
##############################################################################

if [ "$enable_process_commands" = true ] ; then
  # Find your processes
  function my_ps() { 
    ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; 
  }

  # Kill by process name
  function killps() {
    local pid pname sig="-TERM"
    if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
      echo "Usage: killps [-SIGNAL] pattern"
      return;
    fi
    if [ $# = 2 ]; then sig=$1 ; fi
    for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} )
    do
      pname=$(my_ps | awk '$1~var { print $5 }' var=$pid )
      if ask "Kill process $pid <$pname> with signal $sig?"
        then kill $sig $pid
      fi
    done
  }
fi

##############################################################################
#                         Custom Information Commands                        #
##############################################################################

if [ "$enable_information_commands" = true ] ; then
  function get_ip() {
    MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' |
      sed -e s/addr://)
    echo ${MY_IP:-"Not connected"}
  }

  # Get host information
  function host_information()
  {
      echo -e "\nYou are logged on ${BRed}$HOST"
      echo -e "\n${BRed}Additional information:$NC " ; uname -a
      echo -e "\n${BRed}Users logged on:$NC " ; w -hs |
               cut -d " " -f1 | sort | uniq
      echo -e "\n${BRed}Current date :$NC " ; date
      echo -e "\n${BRed}Machine stats :$NC " ; uptime
      echo -e "\n${BRed}Memory stats :$NC " ; free
      echo -e "\n${BRed}Local IP Address :$NC" ; get_ip
      echo -e "\n${BRed}Open connections :$NC "; netstat -pan --inet;
      echo
  }
fi

##############################################################################
#                           Miscellaneous Commands                           #
##############################################################################

if [ "$enable_misc_commands" = true ] ; then
  # Repeat a function 'n' times
  #   repeat <number> <command>
  function repeat() {
      local i max
      max=$1; shift;
      for ((i=1; i <= max ; i++)); do
          eval "$@";
      done
  }

  # Ask whether something should be done
  #   ask <question>
  function ask() {
      echo -n "$@" '[y/n] ' ; read ans
      case "$ans" in
          y*|Y*) return 0 ;;
          *) return 1 ;;
      esac
  }

  # Get who created a corefile
  #   corename <file>
  function corename()
  {
      for file ; do
          echo -n $file : ; gdb --core=$file --batch | head -1
      done
  }
fi

##############################################################################
#                          Programmable Completion                           #
##############################################################################

if [ "$enable_programmable_completion" = true ] ; then
  # Enable auto-complete for programs
  if ! shopt -oq posix; then
    if [ -f /usr/share/bash-completion/bash_completion ]; then
      . /usr/share/bash-completion/bash_completion
    elif [ -f /etc/bash_completion ]; then
      . /etc/bash_completion
    fi
  fi

  shopt -s extglob

  complete -A hostname   rsh rcp telnet rlogin ftp ping disk
  complete -A export     printenv
  complete -A variable   export local readonly unset
  complete -A enabled    builtin
  complete -A alias      alias unalias
  complete -A function   function
  complete -A user       su mail finger

  complete -A helptopic  help     # Currently same as builtins.
  complete -A shopt      shopt
  complete -A stopped -P '%' bg
  complete -A job -P '%'     fg jobs disown

  complete -A directory  mkdir rmdir
  complete -A directory   -o default cd

  # Compression
  complete -f -o default -X '*.+(zip|ZIP)'  zip
  complete -f -o default -X '!*.+(zip|ZIP)' unzip
  complete -f -o default -X '*.+(z|Z)'      compress
  complete -f -o default -X '!*.+(z|Z)'     uncompress
  complete -f -o default -X '*.+(gz|GZ)'    gzip
  complete -f -o default -X '!*.+(gz|GZ)'   gunzip
  complete -f -o default -X '*.+(bz2|BZ2)'  bzip2
  complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2
  complete -f -o default -X '!*.+(zip|ZIP|z|Z|gz|GZ|bz2|BZ2)' extract


  # Documents - Postscript,pdf,dvi.....
  complete -f -o default -X '!*.+(ps|PS)'  gs ghostview ps2pdf ps2ascii
  complete -f -o default -X \
  '!*.+(dvi|DVI)' dvips dvipdf xdvi dviselect dvitype
  complete -f -o default -X '!*.+(pdf|PDF)' acroread pdf2ps
  complete -f -o default -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?\
  (.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv
  complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
  complete -f -o default -X '!*.tex' tex latex slitex
  complete -f -o default -X '!*.lyx' lyx
  complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps
  complete -f -o default -X \
  '!*.+(doc|DOC|xls|XLS|ppt|PPT|sx?|SX?|csv|CSV|od?|OD?|ott|OTT)' soffice

  # Multimedia
  complete -f -o default -X \
  '!*.+(gif|GIF|jp*g|JP*G|bmp|BMP|xpm|XPM|png|PNG)' xv gimp ee gqview
  complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321
  complete -f -o default -X '!*.+(ogg|OGG)' ogg123
  complete -f -o default -X \
  '!*.@(mp[23]|MP[23]|ogg|OGG|wav|WAV|pls|\
  m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' xmms
  complete -f -o default -X '!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|\
  asf|vob|VOB|bin|dat|vcd|ps|pes|fli|viv|rm|ram|yuv|mov|MOV|qt|\
  QT|wmv|mp3|MP3|ogg|OGG|ogm|OGM|mp4|MP4|wav|WAV|asx|ASX)' xine

  complete -f -o default -X '!*.pl'  perl perl5

  #  This is a 'universal' completion function - it works when commands have
  #+ a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
  #  Needs the '-o' option of grep
  #+ (try the commented-out version if not available).

  #  First, remove '=' from completion word separators
  #+ (this will allow completions like 'ls --color=auto' to work correctly).

  COMP_WORDBREAKS=${COMP_WORDBREAKS/=/}

  _get_longopts()
  {
    #$1 --help | sed  -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \
    #grep ^"$2" |sort -u ;
      $1 --help | grep -o -e "--[^[:space:].,]*" | grep -e "$2" |sort -u
  }

  _longopts()
  {
      local cur
      cur=${COMP_WORDS[COMP_CWORD]}

      case "${cur:-*}" in
         -*)      ;;
          *)      return ;;
      esac

      case "$1" in
         \~*)     eval cmd="$1" ;;
           *)     cmd="$1" ;;
      esac
      COMPREPLY=( $(_get_longopts ${1} ${cur} ) )
  }
  complete  -o default -F _longopts configure bash
  complete  -o default -F _longopts wget id info a2ps ls recode

  _tar()
  {
      local cur ext regex tar untar

      COMPREPLY=()
      cur=${COMP_WORDS[COMP_CWORD]}

      # If we want an option, return the possible long options.
      case "$cur" in
          -*)     COMPREPLY=( $(_get_longopts $1 $cur ) ); return 0;;
      esac

      if [ $COMP_CWORD -eq 1 ]; then
          COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) )
          return 0
      fi

      case "${COMP_WORDS[1]}" in
          ?(-)c*f)
              COMPREPLY=( $( compgen -f $cur ) )
              return 0
              ;;
          +([^Izjy])f)
              ext='tar'
              regex=$ext
              ;;
          *z*f)
              ext='tar.gz'
              regex='t\(ar\.\)\(gz\|Z\)'
              ;;
          *[Ijy]*f)
              ext='t?(ar.)bz?(2)'
              regex='t\(ar\.\)bz2\?'
              ;;
          *)
              COMPREPLY=( $( compgen -f $cur ) )
              return 0
              ;;
      esac

      if [[ "$COMP_LINE" == tar*.$ext' '* ]]; then
          # Complete on files in tar file.
          #
          # Get name of tar file from command line.
          tar=$( echo "$COMP_LINE" | \
                          sed -e 's|^.* \([^ ]*'$regex'\) .*$|\1|' )
          # Devise how to untar and list it.
          untar=t${COMP_WORDS[1]//[^Izjyf]/}

          COMPREPLY=( $( compgen -W "$( echo $( tar $untar $tar \
                                  2>/dev/null ) )" -- "$cur" ) )
          return 0

      else
          # File completion on relevant files.
          COMPREPLY=( $( compgen -G $cur\*.$ext ) )

      fi

      return 0
  }

  complete -F _tar -o default tar

  _make()
  {
      local mdef makef makef_dir="." makef_inc gcmd cur prev i;
      COMPREPLY=();
      cur=${COMP_WORDS[COMP_CWORD]};
      prev=${COMP_WORDS[COMP_CWORD-1]};
      case "$prev" in
          -*f)
              COMPREPLY=($(compgen -f $cur ));
              return 0
              ;;
      esac;
      case "$cur" in
          -*)
              COMPREPLY=($(_get_longopts $1 $cur ));
              return 0
              ;;
      esac;

      # ... make reads
      #          GNUmakefile,
      #     then makefile
      #     then Makefile ...
      if [ -f ${makef_dir}/GNUmakefile ]; then
          makef=${makef_dir}/GNUmakefile
      elif [ -f ${makef_dir}/makefile ]; then
          makef=${makef_dir}/makefile
      elif [ -f ${makef_dir}/Makefile ]; then
          makef=${makef_dir}/Makefile
      else
         makef=${makef_dir}/*.mk         # Local convention.
      fi

      #  Before we scan for targets, see if a Makefile name was
      #+ specified with -f.
      for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
          if [[ ${COMP_WORDS[i]} == -f ]]; then
              # eval for tilde expansion
              eval makef=${COMP_WORDS[i+1]}
              break
          fi
      done
      [ ! -f $makef ] && return 0

      # Deal with included Makefiles.
      makef_inc=$( grep -E '^-?include' $makef |
                   sed -e "s,^.* ,"$makef_dir"/," )
      for file in $makef_inc; do
          [ -f $file ] && makef="$makef $file"
      done

      #  If we have a partial word to complete, restrict completions
      #+ to matches of that word.
      if [ -n "$cur" ]; then gcmd='grep "^$cur"' ; else gcmd=cat ; fi

      COMPREPLY=( $( awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
                                 {split($1,A,/ /);for(i in A)print A[i]}' \
                                  $makef 2>/dev/null | eval $gcmd  ))

  }

  complete -F _make -X '+($*|*.[cho])' make gmake pmake

  _killall()
  {
      local cur prev
      COMPREPLY=()
      cur=${COMP_WORDS[COMP_CWORD]}

      #  Get a list of processes
      #+ (the first sed evaluation
      #+ takes care of swapped out processes, the second
      #+ takes care of getting the basename of the process).
      COMPREPLY=( $( ps -u $USER -o comm  | \
          sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
          awk '{if ($0 ~ /^'$cur'/) print $0}' ))

      return 0
  }

  complete -F _killall killall killps
fi