Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call getopts in bash multiple times

Tags:

bash

getopt

I have a common library that I use from several scripts that parses command line options, however I also want my individual scripts to be able to process arguments as well... e.g.

common.sh:

function get_options {
    echo -e "in getoptions"
    echo $OPTIND
    while getopts ":ab:" optionName; do
       [ ... processing code ... ]
    done
}

a.sh

. ./common.sh

function get_local_options {
    echo -e "in getoptions"
    echo $OPTIND
    while getopts ":xy:" optionName; do
       [ ... processing code ... ]
    done
}

get_local_options $*
OPTIND=1
get_options $*

The problem si that if I call a.sh with:

a.sh -x -y foo -a -b bar

get_options stops processing at "foo" as it stops at the first "non-option"

Any way around this without rewriting things myself?

like image 688
Hortitude Avatar asked Oct 21 '25 08:10

Hortitude


2 Answers

foo() {
  unset OPTIND
  while getopts ...
  do
  done
}
like image 54
Bishop B Avatar answered Oct 24 '25 00:10

Bishop B


Just have your common script provide a list of common options and functions for handling those, then have the other scripts add to the option list any options which they can handle:

common.sh

OPTS="ab:hv"

common_usage() {
  echo "Common options:"
  echo "  -a     ..."
  echo "  -b arg ..."
  echo "  -h     Show usage"
  echo "  -v     Be verbose"
}

handle_common_opts() {
  case "$1" in
    a) handle_opt_a ;;
    b) handle_opt_b "$2" ;;
    h) usage; exit 0 ;;
    v) be_verbose ;;
  esac
}

a.sh

. common.sh

OPTS="${OPTS}xy:"

usage() {
  echo "Usage: $PROG [options] [arguments...]"
  echo
  common_usage
  echo
  echo "Specific options:"
  echo "  -x     ..."
  echo "  -y arg ..."
}

while getopts "$OPTS" OPT; do
  handle_common_opts "$OPT" "$OPTARG"
  case "$OPT" in
    x) handle_opt_x ;;
    y) handle_opt_y "$OPTARG" ;;
    \?) usage; exit 1 ;;
  esac
done
shift $((OPTIND-1))

handle_remaining_args "$@"

This has the following advantages: no need to play tricks with the internal houskeeping of getopts, the user can specify common and specific options in any order, it handles unrecognized options in a single place, and also makes the usage functions easier to maintain.

like image 35
ack Avatar answered Oct 23 '25 22:10

ack