Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In bash, how can I have a set of arguments in any random order? Like a key-value pair?

Tags:

bash

Example:

./myscript --ip 192.168.1.1 --port 1985

or another possible

./myscript --port 1985 --ip 192.168.1.1

I want to allow my script to take a set of arguments, in any order

./myscript a b c d
./myscript d c b a
./myscript b d a c

Etcetera

like image 925
stackoverflow Avatar asked Sep 23 '11 12:09

stackoverflow


3 Answers

take a look at getopts

getopts: getopts optstring name [arg]
Parse option arguments.

Getopts is used by shell procedures to parse positional parameters as options.

OPTSTRING contains the option letters to be recognized; if a letter is followed by a colon, the option is expected to have an argument, which should be separated from it by white space.

Each time it is invoked, getopts will place the next option in the shell variable $name, initializing name if it does not exist, and the index of the next argument to be processed into the shell variable OPTIND. OPTIND is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, getopts places that argument into the shell variable OPTARG.

getopts reports errors in one of two ways. If the first character of OPTSTRING is a colon, getopts uses silent error reporting. In this mode, no error messages are printed. If an invalid option is seen, getopts places the option character found into OPTARG. If a required argument is not found, getopts places a ':' into NAME and sets OPTARG to the option character found. If getopts is not in silent mode, and an invalid option is seen, getopts places '?' into NAME and unsets OPTARG. If a required argument is not found, a '?' is placed in NAME, OPTARG is unset, and a diagnostic message is printed.

If the shell variable OPTERR has the value 0, getopts disables the printing of error messages, even if the first character of OPTSTRING is not a colon. OPTERR has the value 1 by default.

Getopts normally parses the positional parameters ($0 - $9), but if more arguments are given, they are parsed instead.

Exit Status:
Returns success if an option is found; fails if the end of options is encountered or an error occurs.

like image 185
c00kiemon5ter Avatar answered Oct 25 '22 02:10

c00kiemon5ter


You can use getopts to parse command-line arguments. This tutorial is quite useful to get started with.

like image 42
cmbuckley Avatar answered Oct 25 '22 02:10

cmbuckley


This simple script takes the port number with p and ip address with i parameter.

while getopts "i:p:" option; do
  case $option in
    i ) ip_address=$OPTARG
    echo "ip address: $ip_address"
    ;;
    p ) port_number=$OPTARG
    echo "port number: $port_number"
    ;;
  esac
done

Can be executed in either ways:

./myscript -i 192.168.1.1 -p 1985

or

./myscript -p 1985 -i 192.168.1.1

When executed it prints:

ip address: 192.168.1.1
port number: 1985

Also as mentioned at http://wiki.bash-hackers.org/howto/getopts_tutorial

Note that getopts is not able to parse GNU-style long options (--myoption) or XF86-style long options (-myoption)

So you cannot use long strings as --port or --ip directly with getopts. However additional workarounds available as described in this link:
http://www.bahmanm.com/blogs/command-line-options-how-to-parse-in-bash-using-getopt

like image 39
Akif Avatar answered Oct 25 '22 02:10

Akif