Bash Script Argument Parsing

Years ago we came up with a halfway decent way to parse arguments for a shell script. I am posting an example template of how we did that. The goals were to have a readable, self-contained script with most of the flexibility of normal command line argument parsing. This version even handles equal signs for assigning values — something we didn’t bother with before.


prog=$(basename "$0")

# Set defaults.

 $prog [<options>] <file1> <file2>
 $prog (-h | --help)
 -n|--number=<num> Number of things (default: $opt_number).
 -v|--verbose Verbose mode.
 -h|--help Show usage.
 <file1> File number 1.
 <file2> File number 2.
This is a template for a bash script that
handles command line options."

while true ; do
 test $# -gt 0 || break
 value=$(echo "$1" | sed -e 's/.*=//')
 test "$value" = "$1" && value=""
 case $1 in
 shift 1
 echo "$usage" >&2
 exit 1
 shift 1
 test "$value" = "" && value="$1" && shift 1

if test $# -lt 2 ; then
 echo "Error: Not enough arguments"
 echo "$usage" >&2
 exit 1

shift 1
shift 1

if test $# -gt 0 ; then
 echo "Error: Too many arguments: $*"
 echo "$usage" >&2
 exit 1

echo "opt_number: $opt_number"
echo "opt_verbose: $opt_verbose"
echo "opt_help: $opt_help"
echo "file1: $file1"
echo "file2: $file2"

Git difftool configuration

meld-mary As of Git 1.6.3 the difftool command was added to Git. This basically lets you use and external merge tool to view/edit your differences by running git difftool instead of the normal diff. I like using Meld, but it works with a bunch of merge tools. It was a bit confusing how to configure it, so here goes:

To figure out which ones you have installed and which are supported:

git difftool --tool-help

For me, the following works to set things up to use Meld without prompting.

sudo apt-get install meld
git config --global diff.tool meld
git config --global difftool.prompt false
git config --global merge.tool meld
git config --global mergetool.meld.cmd 'meld "$BASE" "$LOCAL" "$REMOTE" --output="$MERGED"'
# Or this one if you like the center pane to be the git conflict file
#git config --global mergetool.meld.cmd 'meld "$BASE" "$MERGED" "$REMOTE" --output="$MERGED"'

In Windows it is a bit more complicated, so it is probably easier to just edit the .gitconfig file.  This also adds the mergetool settings to use Meld.  I added the following to my configuration:

	tool = meld
    prompt = false
[difftool "meld"]
	path = C:\\Program Files (x86)\\Meld\\Meld.exe
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines.  
    # It chooses which is the one being
    # edited (center pane).
    #cmd = \"C:\\Program Files (x86)\\Meld\\Meld.exe\" "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = \"C:\\Program Files (x86)\\Meld\\Meld.exe\" "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"