Getting program input parameters
Retrieving program input parameters or arguments is very similar to function parameters at the most basic level. They can be accessed in the same fashion as $1 (arg1), $2 (arg2), $3 (arg3), and so on. However, so far, we have seen a concept called flags, which allows you to perform neat things such as-l, --long-version, -v 10, --verbosity=10. Flags are effectively a user-friendly way to pass parameters or arguments to a program at runtime. For example:
bash myProgram.sh -v 99 --name=Ron -l Brash
Now that you know what flags are and how they can be helpful to improve your script, use the following section as a template.
Passing your program flags
After going into your shell and opening a new file in your favorite editor, let's get started by creating a Bash script that does the following:
- When no flags or arguments are specified, prints out a help message
- When either the
-hor--helpflags are set, it prints out a help message - When the
-for--firstnameflags are set, it sets the the first name variable - When the
-lor--lastnameflags are set, it sets the the last name variable - When both the
firstnameandlastnameflags are set, it prints a welcome message and returns without error
In addition to the basic logic, we can see that the code leverages a piece of functionality called getopts. Getopts allows us to grab the program parameter flags for use within our program. There are also primitives, which we have learned as well—conditional logic, while loop, and case/switch statements. Once a script develops into more than a simple utility or provides more than a single function, the more basic Bash constructs will become commonplace.
#!/bin/bash
HELP_STR="usage: $0 [-h] [-f] [-l] [--firstname[=]<value>] [--lastname[=]<value] [--help]"
# Notice hidden variables and other built-in Bash functionality
optspec=":flh-:"
while getopts "$optspec" optchar; do
case "${optchar}" in
-)
case "${OPTARG}" in
firstname)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
FIRSTNAME="${val}"
;;
lastname)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
LASTNAME="${val}"
;;
help)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
;;
*)
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then
echo "Found an unknown option --${OPTARG}" >&2
fi
;;
esac;;
f)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
FIRSTNAME="${val}"
;;
l)
val="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
LASTNAME="${val}"
;;
h)
echo "${HELP_STR}" >&2
exit 2
;;
*)
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then
echo "Error parsing short flag: '-${OPTARG}'" >&2
exit 1
fi
;;
esac
done
# Do we have even one argument?
if [ -z "$1" ]; then
echo "${HELP_STR}" >&2
exit 2
fi
# Sanity check for both Firstname and Lastname
if [ -z "${FIRSTNAME}" ] || [ -z "${LASTNAME}" ]; then
echo "Both firstname and lastname are required!"
exit 3
fi
echo "Welcome ${FIRSTNAME} ${LASTNAME}!"
exit 0When we execute the preceding program, we should expect responses similar to the following:
$ bash flags.sh usage: flags.sh [-h] [-f] [-l] [--firstname[=]<value>] [--lastname[=]<value] [--help] $ bash flags.sh -h usage: flags.sh [-h] [-f] [-l] [--firstname[=]<value>] [--lastname[=]<value] [--help] $ bash flags.sh --fname Bob Both firstname and lastname are required! rbrash@moon:~$ bash flags.sh --firstname To -l Mater Welcome To Mater!