-
-
Save jehiah/855086 to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# | |
# a simple way to parse shell script arguments | |
# | |
# please edit and use to your hearts content | |
# | |
ENVIRONMENT="dev" | |
DB_PATH="/data/db" | |
function usage() | |
{ | |
echo "if this was a real script you would see something useful here" | |
echo "" | |
echo "./simple_args_parsing.sh" | |
echo "\t-h --help" | |
echo "\t--environment=$ENVIRONMENT" | |
echo "\t--db-path=$DB_PATH" | |
echo "" | |
} | |
while [ "$1" != "" ]; do | |
PARAM=`echo $1 | awk -F= '{print $1}'` | |
VALUE=`echo $1 | awk -F= '{print $2}'` | |
case $PARAM in | |
-h | --help) | |
usage | |
exit | |
;; | |
--environment) | |
ENVIRONMENT=$VALUE | |
;; | |
--db-path) | |
DB_PATH=$VALUE | |
;; | |
*) | |
echo "ERROR: unknown parameter \"$PARAM\"" | |
usage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
echo "ENVIRONMENT is $ENVIRONMENT"; | |
echo "DB_PATH is $DB_PATH"; |
I wrote this - https://github.com/unfor19/bargs - exactly for this need, so you don't need to write down while case esac shift
thingy, a very simple and flexible implementation
I wrote another optional parser and generator that POSIX-compliant and works with all POSIX shells (e.g. dash, bash 2.0+, ksh88, zsh 3.1+, busybox ash). It is a pure shell function and aims to be compatible with POSIX and GNU option syntax. Its code is as fast and small as possible, and the CC0 license allows you to embed it freely in your scripts. https://github.com/ko1nksm/getoptions
2020-11-19: Add support for abbreviated long options and subcommands.
I used the work of @hypersoft for my own script and made some bug fixes and improvements to meet my needs. Giving back the results, which I have simplified for the sake of clarity.
#!/bin/bash
DIRNAME=$(dirname -- $0)
BASENAME=$(basename -- $0)
usage()
{
echo "USAGE: $BASENAME [OPTIONS]"
echo
echo "OPTIONS"
echo " -r, --require-approval Ask user for security approval when deploying CDK stacks"
echo
echo " Features deployed will be the sum \(union\) of the following options, if none"
echo " is specified then all features will be deployed by default. \(Specify each"
echo " option separately, as a group like -yld will not be understood\)"
echo " -a, --all Deploy all features"
echo " -y, --analytics Deploy the analytics features"
echo
echo " -v, --verbose [level] Output additional info. (can use -v=2 form also)"
echo " Possible levels:"
echo " 0 \(default\) essential info"
echo " 1 more info"
echo " 2 even more info"
echo
echo "POSITIONAL PARAMETERS"
echo " none"
exit
}
# default values for flags. always use 1 for true and 0 for false. use strings for qualifiers.
REQUIREAPPROVAL="--require-approval never"
DEFAULT=1
ALL=0
ANALYTICS=0
VERBOSELEVEL="0"
while [[ $# > 0 ]]
do
echo num $#
[[ $1 =~ ^-h$|^--help$ ]] && {
usage
};
# -- marks end of options and start of positional parameters
[[ $1 == -- ]] && { shift; break; };
# options without parameters
[[ $1 =~ ^-r$|^--require-approval$ ]] && { REQUIREAPPROVAL=; shift 1; continue; };
[[ $1 =~ ^-a$|^--all$ ]] && { ALL=1; DEFAULT=0; shift 1; continue; };
[[ $1 =~ ^-y$|^--analytics$ ]] && { ANALYTICS=1; DEFAULT=0; shift 1; continue; };
# verbose option with optional value. e.g. -v, -v 0, -v 1, --verbose, --verbose 1
[[ $1 =~ ^-v$|^--verbose$ ]] && {
shift 1
[[ $# == 0 ]] && { continue; };
VERBOSELEVEL="$1"
};
# verbose option with = value. e.g. -v=0, -v=1, -v=2, --verbose=1 etc.
[[ $1 =~ ^-v=|^--verbose= ]] && {
VERBOSELEVEL="${1#*=}"
shift 1
continue;
};
break;
done
# validate string parameters
[[ ! $VERBOSELEVEL =~ ^[0-2]$ ]] && {
echo illegal --verbose parameter $VERBOSELEVEL
usage
};
# if verbose 1 or 2
[[ ! $VERBOSELEVEL =~ ^[1-2]$ ]] && {
echo DEFAULT == $DEFAULT
echo ALL == $ALL
echo ANALYTICS == $ANALYTICS
};
# the default is to deploy all stacks
ALL=$(( $ALL || $DEFAULT ))
# Logic for which stacks are deployed based on the features needed
CFNMAIN=$(( $ALL ))
CFNANALYTICS=$(( $ALL || $ANALYTICS ))
# if verbose 2 only
[[ ! $VERBOSELEVEL =~ ^2$ ]] && {
echo CFNMAIN = $CFNMAIN
echo CFNANALYTICS = $CFNANALYTICS
};
[[ $CFNMAIN ]] && {
echo cdk synth cfnMain
echo cdk deploy $REQUIREAPPROVAL cfnMain
};
[[ $CFNANALYTICS ]] && {
echo cdk synth cfnAnalytics
echo cdk deploy $REQUIREAPPROVAL cfnAnalytics
};
echo ":) Deployment complete"
#!/bin/sh
DIRNAME=$(dirname -- $0)
BASENAME=$(basename -- $0)usage()
{
echo "USAGE: $BASENAME [OPTIONS]"
echo
echo "OPTIONS"
echo " -r, --require-approval Ask user for security approval when deploying CDK stacks"
echo
echo " Features deployed will be the sum (union) of the following options, if none"
echo " is specified then all features will be deployed by default. (Specify each"
echo " option separately, as a group like -yld will not be understood)"
echo " -a, --all Deploy all features"
echo " -y, --analytics Deploy the analytics features"
echo
echo " -v, --verbose [level] Output additional info. (can use -v=2 form also)"
echo " Possible levels:"
echo " 0 (default) essential info"
echo " 1 more info"
echo " 2 even more info"
echo
echo "POSITIONAL PARAMETERS"
echo " none"
exit
}default values for flags. always use 1 for true and 0 for false. use strings for qualifiers.
REQUIREAPPROVAL="--require-approval never"
DEFAULT=1
ALL=0
ANALYTICS=0
VERBOSELEVEL="0"while [[ $# > 0 ]]
do
echo num $#
[[$1 =~ ^-h$ |^--help$ ]] && {
usage
};
# -- marks end of options and start of positional parameters
[[ $1 == -- ]] && { shift; break; };# options without parameters [[ $1 =~ ^-r$|^--require-approval$ ]] && { REQUIREAPPROVAL=; shift 1; continue; }; [[ $1 =~ ^-a$|^--all$ ]] && { ALL=1; DEFAULT=0; shift 1; continue; }; [[ $1 =~ ^-y$|^--analytics$ ]] && { ANALYTICS=1; DEFAULT=0; shift 1; continue; }; # verbose option with optional value. e.g. -v, -v 0, -v 1, --verbose, --verbose 1 [[ $1 =~ ^-v$|^--verbose$ ]] && { shift 1 [[ $# == 0 ]] && { continue; }; VERBOSELEVEL="$1" }; # verbose option with = value. e.g. -v=0, -v=1, -v=2, --verbose=1 etc. [[ $1 =~ ^-v=|^--verbose= ]] && { VERBOSELEVEL="${1#*=}" shift 1 continue; }; break;
done
validate string parameters
[[ !
$VERBOSELEVEL =~ ^[0-2]$ ]] && {
echo illegal --verbose parameter $VERBOSELEVEL
usage
};if verbose 1 or 2
[[ !
$VERBOSELEVEL =~ ^[1-2]$ ]] && {
echo DEFAULT == $DEFAULT
echo ALL == $ALL
echo ANALYTICS == $ANALYTICS
};the default is to deploy all stacks
ALL=$(( $ALL || $DEFAULT ))
Logic for which stacks are deployed based on the features needed
CFNMAIN=$(( $ALL ))
CFNANALYTICS=$(( $ALL || $ANALYTICS ))if verbose 2 only
[[ !
$VERBOSELEVEL =~ ^2$ ]] && {
echo CFNMAIN = $CFNMAIN
echo CFNANALYTICS = $CFNANALYTICS
};[[ $CFNMAIN ]] && {
echo cdk synth cfnMain
echo cdk deploy $REQUIREAPPROVAL cfnMain
};[[ $CFNANALYTICS ]] && {
echo cdk synth cfnAnalytics
echo cdk deploy $REQUIREAPPROVAL cfnAnalytics
};echo ":) Deployment complete"
It's marked as /bin/sh, but will not work in posix compliant shells (such as dash).
The "[[ ]]" for comparisons, "~=" regex matching, and "==" instead of "=" are all not supported.
If you prefer using those to the posix equivalents, the easiest thing to do would be to just change it to /bin/bash since those are bashisms.
:)
/bin/bash it is, then!
@Pagliacii
If you change
if [[ $VALUE == $PARAM ]]
" toif [ "$VALUE" = "$PARAM" ]
it will be more portable.The code in the OP was written to be run as /bin/sh, so the [[ ]] and == parts could be a problem since they're not POSIX.
Also, I think it's better to change PARAM=
printf "%s\n" $1 | awk -F= '{print $1}'
to PARAM="$(printf "%s\n" $1 | awk -F= '{print $1}')"and VALUE=
printf "%s\n" $1 | sed 's/^[^=]*=//g'
to VALUE="$(printf "%s\n" $1 | sed 's/^[^=]*=//g')"