Search code examples
bashshell

How to get arguments with flags in Bash


I know that I can easily get positioned parameters like this in bash:

$0 or $1

I want to be able to use flag options like this to specify for what each parameter is used:

mysql -u user -h host

What is the best way to get -u param value and -h param value by flag instead of by position?


Solution

  • This is the idiom I usually use:

    while test $# -gt 0; do
      case "$1" in
        -h|--help)
          echo "$package - attempt to capture frames"
          echo " "
          echo "$package [options] application [arguments]"
          echo " "
          echo "options:"
          echo "-h, --help                show brief help"
          echo "-a, --action=ACTION       specify an action to use"
          echo "-o, --output-dir=DIR      specify a directory to store output in"
          exit 0
          ;;
        -a)
          shift
          if test $# -gt 0; then
            export PROCESS=$1
          else
            echo "no process specified"
            exit 1
          fi
          shift
          ;;
        --action*)
          export PROCESS=`echo $1 | sed -e 's/^[^=]*=//g'`
          shift
          ;;
        -o)
          shift
          if test $# -gt 0; then
            export OUTPUT=$1
          else
            echo "no output dir specified"
            exit 1
          fi
          shift
          ;;
        --output-dir*)
          export OUTPUT=`echo $1 | sed -e 's/^[^=]*=//g'`
          shift
          ;;
        *)
          break
          ;;
      esac
    done
    

    Key points are:

    • $# is the number of arguments
    • while loop looks at all the arguments supplied, matching on their values inside a case statement
    • shift takes the first one away. You can shift multiple times inside of a case statement to take multiple values.