Skip to content

Instantly share code, notes, and snippets.

@danielhanold
Created January 7, 2020 14:58
Show Gist options
  • Save danielhanold/8e7edfc6b4e4cca190701d5c452c03f4 to your computer and use it in GitHub Desktop.
Save danielhanold/8e7edfc6b4e4cca190701d5c452c03f4 to your computer and use it in GitHub Desktop.
#! /bin/bash
# See https://stackoverflow.com/questions/36495669/difference-between-terms-option-argument-and-parameter
# for the difference between:
# 1. Option
# 2. Parameter
# 3. Shell Parameter
# Test script to show how named arguments can be passed directly in a shell script.
# Uses a combination of while, case, and the the number of arguments defined in $#.
# List of required options.
last_name=
age=
# List of optional options.
first_name=
ethnicity=
# List of options with no parameters.
verbose=
# Basic processing with tolerance for equal signs or whitespace.
# Example: ./named_arg_processing_basic.sh -a 16 -l=Hill -f James --ethnicity=Caucasian
# Example 2: ./named_arg_processing_basic.sh -a 16 -l=Hill -f James -v --ethnicity=Caucasian
# Example 3: ./named_arg_processing_basic.sh -a 16 --invalid=this -l=Hill -f James -v --ethnicity=Caucasian -- 'Additional parameters' another parameter
while [ $# -gt 0 ]
do
echo "Arg 1: $1"
echo "Arg 2: $2"
# For each argument, determine if:
# 1. Argument is an option with a parameter
# 2. If argument is an option with a parameter, parameter is separated with equal sign
# 2. Argument is an option without a parameter
if echo "$1" | grep -q '^-' && echo "$1" | grep -vq '=' && \
(echo "$2" | grep -q '^-' || test -z "$2")
# Argument is option without parameter or is last argument.
then
ARG_OPTION=$1
ARG_PARAMETER=$1
SHIFT_NUM=1
elif echo "$1" | grep -q '^\-.*='
# Argument is option with parameter, separated by equal sign.
then
ARG_OPTION=$(echo "$1" | grep -o '.*=' | grep -o '[^=]*')
ARG_PARAMETER=$(echo "$1" | grep -o '[^=]*$')
SHIFT_NUM=1
else
# Argument is option with parameter, not separated by equal sign.
ARG_OPTION=$1
ARG_PARAMETER=$2
SHIFT_NUM=2
fi
echo "Val 1: $ARG_OPTION"
echo "Val 2: $ARG_PARAMETER"
case $ARG_OPTION in
-l|--last_name) last_name=$ARG_PARAMETER
;;
-a|--age) age=$ARG_PARAMETER
;;
-f|--first_name) first_name=$ARG_PARAMETER
;;
-v|--verbose) verbose=true
;;
-e|--ethnicity) ethnicity=$ARG_PARAMETER
;;
--) shift
break
;;
-*|--*) echo "unrecognized option: $ARG_OPTION" >&2
# Enable exit if you want to continue processing.
# exit 1
;;
*) break
;;
esac
# Add a newline.
echo ""
# Shift arguments forward.
shift $SHIFT_NUM
done
# # Using Bash getopts function that comes with better features:
# # - Included error handling
# # - Indicates that an option takes an argument (prefix with :)
# # - Built-in support for -- to indicate that there are no more named arguments
# #
# # However, getopts has one HUGE downfall: It does not allow for optional parameters.
# # When an option requires a parameter, it needs to be required.
# # @see https://stackoverflow.com/questions/11517139/optional-option-argument-with-getopts for example.
# #
# # Example 1: ./named_arg_processing_basic.sh -a 16 -f Daniel -e=Caucasian
# # Example 2: ./named_arg_processing_basic.sh -a 16 -l=Hanold -f Daniel -e=Caucasian
# while getopts l:a:e:f: opt;
# do
# echo "Option: $opt"
# echo "Parameter: $OPTARG"
# echo
#
# CLEANED_ARG=$(echo $OPTARG | sed 's/^=//')
# case "$opt" in
# l) last_name=$CLEANED_ARG
# ;;
# a) age=$CLEANED_ARG
# ;;
# f) first_name=$CLEANED_ARG
# ;;
# e) ethnicity=$CLEANED_ARG
# ;;
# esac
# done
#
# # getops shifts options itself. Shifting after the loop will ensure that
# # "$@" only contains the non-option arguments to the script/function.
# shift $((OPTIND - 1))
echo "=== Debug Code ==="
echo "First Name is $first_name"
echo "Last Name is $last_name"
echo "Age is $age"
echo "Ethnicity is $ethnicity"
echo "Verbosity is $verbose"
echo "=== End Debug Code ==="
echo
# Print out variables.
if [ -n "$first_name" -a -n "$ethnicity" ];
then
printf "Person %s %s is %s years of age. His ethnicity is %s.\n" $first_name $last_name $age $ethnicity
elif [ -n "$first_name" -a -z "$ethnicity" ];
then
printf "Person %s %s is %s years of age.\n" $first_name $last_name $age
elif [ -z "$first_name" -a -n "$ethnicity" ];
then
printf "Person %s is %s years of age. His ethnicity is %s.\n" $last_name $age $ethnicity
else
printf "Person %s is %s years of age.\n" $last_name $age
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment