Skip to content

Instantly share code, notes, and snippets.

@jehiah
Created March 4, 2011 16:56
Show Gist options
  • Save jehiah/855086 to your computer and use it in GitHub Desktop.
Save jehiah/855086 to your computer and use it in GitHub Desktop.
a simple way to parse shell script arguments
#!/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";
@alanmur
Copy link

alanmur commented Nov 8, 2021

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"

@slycordinator
Copy link

#!/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.

:)

@alanmur
Copy link

alanmur commented Nov 9, 2021

/bin/bash it is, then!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment