Bash: Your forgotten friend (part 3)

For the final installment of Bash: Your forgotten friend (see: part one and part two), I'll be going over the functions I use to make life easy. For those unfamiliar, functions aren't as scary as they sound. They're basically things that are too complex for simple aliases but aren't worth writing an entire bash script to do. This doesn't, however, mean that they aren't powerful. You can pack a lot of functionality into these small functions.

The first function is a relatively easy one. It starts up a django project with a specific DJANGOSETTINGSMODULE defined. I found this especially helpful when working with a project that had multiple settings file.

  # Courtside Development Shortcut
  cs.dj () {
    DJANGO_SETTINGS_MODULE=settings.development_stephen python manage.py $@
  }

There are a few key bits to this function which are important to understand. The function name is cs.dj The ()'s let you know that its a function. Inside, the text is largely just bash script with a parameter of $@, which means "every argument passed into the script". You can specifically target parameter numbers with $1, $2 and so on.

The next script is a quick shortcut for running vim as a super user (something I tend to forget about).

  svim () {
    # Run vim as super user
    command sudo vim $@
  }

Very similar to the previous script. The next script is a bit different. It takes a single argument of a file name and attempts to extract the file based on its file extension.

  extract () {
    if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2)        tar xjf $1        ;;
        *.tar.gz)         tar xzf $1        ;;
        *.bz2)            bunzip2 $1        ;;
        *.rar)            unrar 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
  }

This script could very easily be altered to take multiple files as arguments and extract them all. Another helper function is mcd which stands for "make and cd". It makes a directory and changes to the directory. Simple, but very helpful.

  mcd () {
    mkdir "$@" && cd "$@"
  }

The next two functions help with figuring out your IP. the first, exip will find your external ip using the service http://myip.dk. The second, lists the IP addresses of all network interfaces on your computer. There are several possible improvements for this script including separating IPs by routable or non-routable, public facing or not, pairing the IPs with their network interface and several more.

  exip () {
    # gather external ip address
    echo -n "Current External IP: "
    curl -s -m 5 http://myip.dk | grep "" | sed -e 's/Your IP address is: //g' -e 's/<\/title>;//g'
  }

  ips () {
    # determine local IP address
    ifconfig | grep "inet " | awk '{ print $2 }'
  }

The next three functions are based on the grep command. The first two grep your file system looking for strings, the second of which returns only the unique file names for each occurrence. The third function greps your running processes and is much easier than piping `ps` output into grep each time.

  dgrep() {
    # A recursive, case-insensitive grep that excludes binary files
    grep -iR "$@" * | grep -v "Binary"
  }
  dfgrep() {
    # A recursive, case-insensitive grep that excludes binary files
    # and returns only unique filenames
    grep -iR "$@" * | grep -v "Binary" | sed 's/:/ /g' | awk '{ print $1 }' | sort | uniq
  }
  psgrep() {
    if [ ! -z $1 ] ; then
      echo "Grepping for processes matching $1..."
      ps aux | grep $1 | grep -v grep
    else
      echo "!! Need name to grep for"
    fi
  }

This last pair of functions is something I was particularly happy with. It grabs your current branch (git) or revision (svn) and displays them in your prompt if they are available for your current directory.

  # The functions..
  parse_git_branch(){ git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'; }
  parse_svn_rev(){ svn info 2> /dev/null | grep "Revision" | sed 's/Revision: \(.*\)/(r\1) /'; }

  # ... And the prompt
  PS1="${BLUE}(${NORMAL}\w${BLUE})${GREEN} \$(parse_svn_rev)\$(parse_git_branch)${NORMAL}\u${BLUE}@\h${RED}\$ ${NORMAL}"

While that is a bit cryptic, it basically filters through the information in git branch and svn info respectively and pulls out the information we want. It pipes all error information (such as "This isn't svn/git!"-style messages) to /dev/null, \*nix's global trash bin.

I hope this was helpful for everyone. I'll be keeping an updated link to my bashprofile here for anyone's future reference.