$myscript.sh -host blah -user blah -pass blah
I want to pass arguments into it.
I'm used to doing $1, $2, $3....but I want to start naming them 
We can use the getopts program/ command to parse the arguments passed to the script in the command line/ terminal by using loops and switch-case statements. Using getopts, we can assign the positional arguments/ parameters from the command line to the bash variables directly.
The special character $# stores the total number of arguments. We also have $@ and $* as wildcard characters which are used to denote all the arguments. We use $$ to find the process ID of the current shell script, while $? can be used to print the exit code for our script.
It mainly utilize the “internal field separator” or IFS , and the read builtin function. The first step is to split the string using new line, with IFS=$'\n' . Then we split using the colon : , and use read -ra vals to split the input and put it in an array.
There are lots of ways to parse arguments in sh. Getopt is good. Here's a simple script that parses things by hand:
#!/bin/sh
# WARNING: see discussion and caveats below
# this is extremely fragile and insecure
while echo $1 | grep -q ^-; do
    # Evaluating a user entered string!
    # Red flags!!!  Don't do this
    eval $( echo $1 | sed 's/^-//' )=$2
    shift
    shift
done
echo host = $host
echo user = $user
echo pass = $pass
echo args = $@
A sample run looks like:
$ ./a.sh -host foo -user me -pass secret some args
host = foo
user = me
pass = secret
args = some args
Note that this is not even remotely robust and massively open to security holes since the script eval's a string constructed by the user. It is merely meant to serve as an example for one possible way to do things. A simpler method is to require the user to pass the data in the environment. In a bourne shell (ie, anything that is not in the csh family):
$ host=blah user=blah pass=blah myscript.sh
works nicely, and the variables $host, $user, $pass will be available in the script.
#!/bin/sh
echo host = ${host:?host empty or unset}
echo user = ${user?user not set}
...
                        Here is a simple way to handle both long and short options:
while [[ $1 == -* ]]; do
    case "$1" in
      -h|--help|-\?) show_help; exit 0;;
      -v|--verbose) verbose=1; shift;;
      -f) if [[ $# > 1 && $2 != -* ]]; then
            output_file=$2; shift 2
          else 
            echo "-f requires an argument" 1>&2
            exit 1
          fi ;;
      --) shift; break;;
      -*) echo "invalid option: $1" 1>&2; show_help; exit 1;;
    esac
done
From How can I handle command-line arguments (options) to my script easily?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With