Created
February 11, 2017 00:43
-
-
Save thoward/e4bfc25098dfd659fb9fa4dba8f9bd51 to your computer and use it in GitHub Desktop.
Basic implementation of CLI subcommands/options parsing in Bash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Private implementation of bar subcommand | |
_bar() { | |
echo "foo_value is $foo_value" | |
echo "flag_value is $flag_value" | |
echo "1: $1" | |
echo "2: $2" | |
echo "3: $3" | |
} | |
# CLI Subcommands Implementation | |
subcommands=() | |
# foo subcommand, simple | |
subcommands+=("foo") | |
foo() { | |
echo "foo" | |
echo "$@" | |
} | |
# bar subcommand, with arg parsing and private implementation invocation | |
subcommands+=("bar") | |
bar() { | |
help_bar() { | |
echo "bar subcommand" | |
echo "--------------" | |
echo | |
echo "Example:" | |
echo " $progname bar --foo value --flag <file1> <file2>" | |
echo | |
echo "Available options:" | |
echo " -f, --foo <value> Sets a foo value. Required." | |
echo " --flag Enables the flag." | |
echo " <file1> Path to file to process. Required." | |
} | |
bar_args=() | |
flag_value=0 | |
# parse named args | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--help) | |
help_bar && exit 0 | |
;; | |
-f|--foo) | |
if [ "$#" -gt 1 ]; then | |
shift | |
foo_value="$1" | |
else | |
echo "ERROR: $1 option requires a value." >&2 | |
help_bar && exit 1 | |
fi | |
;; | |
--flag) | |
flag_value=1 | |
;; | |
*) | |
bar_args+=("$1") | |
;; | |
esac | |
shift | |
done | |
if [[ ! "$foo_value" ]]; then | |
echo "ERROR: --foo option is required." >&2 | |
help_bar && exit 1 | |
fi | |
if [[ ! "$bar_args[0]" ]]; then | |
echo "ERROR: <file1> is required." >&2 | |
help_bar && exit 1 | |
fi | |
foo_value="$foo_value" flag_value="$flag_value" _bar "${bar_args[@]}" | |
} | |
# CLI Main Implementation | |
progname=$(basename $0) | |
is_function() { declare -Ff "$1" >/dev/null; } | |
help_commands() { | |
echo "Available Commands:" | |
for command in "${subcommands[@]}"; do | |
echo " $command" | |
done | |
echo "" | |
echo "Example:" | |
echo " $progname $subcommands --help" | |
} | |
if [ "$#" -eq 0 ]; then | |
echo "ERROR: No command specified." >&2 | |
help_commands && exit 1 | |
fi | |
case "$1" in | |
--help) | |
help_commands && exit 1 | |
;; | |
*) | |
subcommand="$1" && shift | |
if ! is_function "${subcommand}"; then | |
echo "ERROR: Unknown command '${subcommand}'" >&2 | |
help_commands && exit 1 | |
fi | |
"${subcommand}" "$@" | |
exit $? | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment