Skip to content

Instantly share code, notes, and snippets.

@thoward
Created February 11, 2017 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thoward/e4bfc25098dfd659fb9fa4dba8f9bd51 to your computer and use it in GitHub Desktop.
Save thoward/e4bfc25098dfd659fb9fa4dba8f9bd51 to your computer and use it in GitHub Desktop.
Basic implementation of CLI subcommands/options parsing in Bash
#!/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