Easy commandline argument parsing in shell script

Here is a fairly easy method which can parse all input arguments passed to a shell script in commandline. This block of code can be either included in top of the script or source it from an external file.

Using this code within a shell script is very simple, just needs to define a global variable named ARGS_INPUT_FORMAT and set appropriate values to it. The argument parsing code will read this variable and set appropriate inputs as well as outputs.

Set values to the variable ARGS_INPUT_FORMAT as shown below.

ARGS_INPUT_FORMAT="OPTION STRING 1|OPTION STRING 2(OPTIONAL)|OPTION STRING N(OPTIONAL):VARIABLE NAME WHICH HOLDS OPTION VALUE:DEFAULT OPTION VALUE(OPTIONAL):DEFAULT OPTION VALUE IF USED AS SWITCH(OPTIONAL)"

Example Usage

These are some examples:

ARGS_INPUT_FORMAT="--ignore-case|-i:check_case:NO:YES"
ARGS_INPUT_FORMAT="--user|-u|-U:username:-1:-1,--ignore-case|-i:ignore_case:NO:YES"
ARGS_INPUT_FORMAT="--color:bgcolor"

Some example script usages are:

./main-script.sh --ignore-case="YES"
./main-script.sh -i -u "Find Linux Help"
./main-script.sh --color="Yellow"

Now access the value of color using variable bgcolor as shown below.

echo "You have chosen $bgcolor color."

There are some advantages of this code; it is not utilizing the capabilities of an external binary but parse using shell script itself. It never shifts or alters the original arguments supplied to main script. It retains the position and count of arguments and can be re-used them inside the main script again.

Argument Parsing Code

for arg_opts in $(echo "$ARGS_INPUT_FORMAT" | tr "," " ") ; do
  opt_names=$(echo "$arg_opts" | cut -d':' -f1)
  opt_var=$(echo "$arg_opts" | cut -d':' -f2)
  opt_def_val=$(echo "$arg_opts" | cut -d':' -f3)
  opt_switch_val=$(echo "$arg_opts" | cut -d':' -f4)
  eval "$opt_var=$opt_def_val"
  for opt_name in $(echo "$opt_names" | tr "|" " ") ; do
    arg_pos=1
    while [ $arg_pos -le $# ] ; do
      case "$(eval "echo $$arg_pos")" in
        "$opt_name="*)
              eval "$opt_var="$(echo "$(eval "echo $$arg_pos")" | sed 's/^'"$opt_name"'=//')""
              ARGS_STAT[$arg_pos]=0
              ;;
        "$opt_name")
              if [ $(expr $arg_pos + 1) -le $# ] && [ $(echo "$(eval "echo $$(expr $arg_pos + 1)")" | grep -c '^-') -eq 0 ] ; then
                ARGS_STAT[$arg_pos]=0
                arg_pos=$(expr $arg_pos + 1)
                eval "$opt_var="$(eval "echo $$arg_pos")""
              else
                eval "$opt_var="$opt_switch_val""
              fi
              ARGS_STAT[$arg_pos]=0
              ;;
        "$opt_name"*)
              eval "$opt_var="$(echo "$(eval "echo $$arg_pos")" | sed 's/^'"$opt_name"'//')""
              ARGS_STAT[$arg_pos]=0
              ;;
        *)
              [ -z "${ARGS_STAT[$arg_pos]}" ] && ARGS_STAT[$arg_pos]=1
              ;;
      esac
      arg_pos=$(expr $arg_pos + 1)
    done
  done
done

Download the script file: [download id="5"]

Script Usage

Define a global variable as ARGS_INPUT_FORMAT and set an appropriate value as shown above. Define this variable on top of the main script.

Save the argument parsing script to an external file and source it into the main script. The same source script can be included in as many scripts wherever  you need argument processing. Even the code block can be directly pasted below the global variable definition inside your main script for better portability.

About Debugging

The script initializes an array variable named ARGS_STAT and set debug values to it. If it finds an invalid argument in commandline, the corresponding array index is updated with a dirty flag “1″.

Here is a sample code which can be included in the main script to display invalid arguments supplied and their respective position numbers.

echo "**Invalid args**"
count=1
while [ $count -le $# ] ; do
  if [ ${ARGS_STAT[$count]} -eq 1 ] ; then
    echo "$(eval echo $$count) ($count)"
  fi
  count=$(expr $count + 1)
done

Download the script file: [download id="6"]

One Response to Easy commandline argument parsing in shell script

  1. Tal says:

    Thanks for this script! It’s very usefull.
    Please add option to get no option aurgument, e.g. files in this form:
    $(COMMAND) (options) FILE1 FILE2, …

    Thanks,
    Tal

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>