04 August 2010

How to parse CLI arguments in bash

Here are some ideas how to parse command line arguments in a bash script.

Using getopt

#!/bin/bash
echo "Before getopt"
for i
do
    echo $i
    done
    args=`getopt abc:d $*`
    set -- $args
    echo "After getopt"
for i
do
  echo "-->$i"
done
The code is from here.

Using getopts

#!/usr/bin/env bash
# cookbook filename: getopts_example
#
# using getopts
#
aflag=
bflag=
while getopts 'ab:' OPTION
do
  case $OPTION in
    a) aflag=1
    ;;
    b) bflag=1
    bval="$OPTARG"
    ;;
    ?) printf "Usage: %s: [-a] [-b value] args\n" $(basename $0) >&2
    exit 2
    ;;
  esac
done
shift $(($OPTIND - 1))

if [ "$aflag" ]
then
  printf "Option -a specified\n"
fi
if [ "$bflag" ]
then
  printf 'Option -b "%s" specified\n' "$bval"
fi
printf "Remaining arguments are: %s\n" "$*"
Source

Using sed

Here is how to parse using a regular expression.
#!/bin/bash 

# For string like part1=part2
# returns part2 
function my_arg_val()
{
  echo $1 | sed 's/\([-a-zA-Z0-9_]*=\)\|\(-[a-z]\)//'
}

# Get args
for i in $*
do
  case $i in
    --option-a=*)
      option_a=`my_arg_val $i` 
      ;;
    --option-b=*)
      option_b=`my_arg_val $i`
      ;;
    --default)
      is_default=YES
      ;;
    *)
      # unknown option
      exit 2
      ;;
  esac
done

echo " 
option_a=$option_a
option_b=$option_b
is_default=$is_default
"

Using $IFS

Here is mine script I finally decided to use:
#!/bin/bash 

# Splits the first argument by delimeter specified by the 2nd parameter 
# E.g. my_split_str $string $delim
# If delimeter is not specified, the func defaults to '='
function my_split_str()
{
  if (( $# <=1 )) 
  then 
    IFS='=' 
  else 
    IFS=$2 
  fi 
  set -- $1
  echo $*
}

# Get args
for i in $*
do
  o=(`my_split_str $i '='`)
  case ${o[0]} in
    --option-a)
      option_a=${o[1]}
      ;;
    --option-b)
      option_b=${o[1]}
      ;;
    --default)
      is_default=YES
      ;;
    *)
      # unknown option
      echo "Unknown option ${o[0]}"
      exit 2
      ;;
  esac
done

echo " 
option_a=$option_a
option_b=$option_b
is_default=$is_default
"