1

I have been using several programs that use the following format when called from the command line:

foo -1 parameter1 -2 parameter2 -3 parameter 3 

and the order of the parameters does not matter as long as they are followed by the correct parameter (I am assuming that dashes followed by something are also parameters). So this would be the same as the above:

foo -2 parameter2 -1 parameter1 -3 parameter3 

What is the most efficient way to write a bash script that can determine which parameter is which by looking first at the < dash >< something > first? I can see writing a huge flow of control with several if statements but I feel like there should be a better way since so many programs use this format.

Lucas Alanis
  • 1,208
  • 3
  • 15
  • 30

2 Answers2

4

You can use getopts

Example :

while getopts "1:2:3:" arg; do
    case "$arg" in
    1)
        echo "Param 1 = $OPTARG"
        ;;
    2)
        echo "Param 2 = $OPTARG"
        ;;
    3)
        echo "Param 3 = $OPTARG"
        ;;
    esac
done

Output :

$ myscript.sh -1 foo -2 bar -3 baz
Param 1 = foo
Param 2 = bar
Param 3 = baz

$ myscript.sh -3 foo -1 bar
Param 3 = foo
Param 1 = bar

SO - example of how to use getopts in bash

Community
  • 1
  • 1
Junior Dussouillez
  • 2,327
  • 3
  • 30
  • 39
  • Common usage, but you should make some more arg checking. E.g. what happens when someone run the script as: `myscript -1 -2 foo` ? – clt60 Jul 10 '14 at 22:58
  • You're right, it's a very simple example. `myscript -1 -2 foo` will output `Param 1 = -2` and foo will be ignored. OP should handle errors. – Junior Dussouillez Jul 10 '14 at 23:08
3

Right off the bat, one way would be to use POSIX "getopts" which you can find a tutorial on by googling it. But using straight bash...

It sounds like you are interested in processing key value pairs. Using your example of:

foo -2 parameter2 -1 parameter1 -3 parameter3 

the straight bash code to process this could look like:

#!/bin/bash

while [[ $# > 1 ]]
do

key="$1"
shift

case $key in
        -1|--parameter1)
        parameter1="$1"
        shift
        ;;
        -2|--parameter2)
        parameter2="$1"
        shift
        ;;
        -3|--parameter3)
        parameter3="$1"
        shift
        ;;
        --default)
        DEFAULT=YES
        shift
        ;;
        *)
        # unknown option
        ;;
esac
done

I included the option to do "--" as well since most command line utilities have dual controls for the same parameters for ease of use.

Hope that helps.

HodorTheCoder
  • 254
  • 2
  • 11