Skip to content

Instantly share code, notes, and snippets.

@mu8086
Last active May 12, 2022 09:05
Show Gist options
  • Save mu8086/adcf6dee4c1d4837aafc5cf1716a4ffb to your computer and use it in GitHub Desktop.
Save mu8086/adcf6dee4c1d4837aafc5cf1716a4ffb to your computer and use it in GitHub Desktop.
[Bash] Dynamically expanded bash menu that can call any function
#!/bin/bash
shopt -s extglob
SCRIPT_NAME="$(basename $0)"
LOG_FILE="${0%.*}.log"
DATE_FORMAT="%F %H:%M:%S %z"
PID_MAX="$(cat /proc/sys/kernel/pid_max)"
PID_FORMAT="%${#PID_MAX}d" # if $PID_MAX=32767 ---> %5d
PID_INFO="$(printf "${PID_FORMAT}" $$)"
exit_log()
{
log "$@"
exit 1
}
get_function_list()
{
local function_list=($(compgen -A function))
remove_reserved_function_from_list # use the same variable 'function_list'
local IFS="|"
echo "${function_list[*]}"
}
log()
{
echo -e "[${PID_INFO}][$(date +"$DATE_FORMAT")] $@" | tee -a ${LOG_FILE}
}
main()
{
local function="${1}"
shift
local available_functions
# get_function_list returns a list of function names separated by |,
# then annotated with bash extglob to make dynamic expansion case work
available_functions="$(get_function_list)" || exit_log "get_function_list failed($?)"
available_functions="+(${available_functions})"
case "${function}" in
start)
"${function}" "$@"
;;
stop)
"${function}" "$@"
;;
${available_functions[*]})
"${function}" "$@"
;;
*)
usage
;;
esac
}
start()
{
log "[${FUNCNAME}] begin"
log "[${FUNCNAME}] end"
}
stop()
{
log "[${FUNCNAME}] begin"
log "[${FUNCNAME}] end"
}
remove_reserved_function_from_list()
{
# use caller function's variable '$function_list' in this function
local reserve_functions=("main" "get_function_list" "remove_reserved_function_from_list")
for reserve_function in "${reserve_functions[@]}"; do
for ((index=0; index<"${#function_list[@]}"; index++)); do
if [ "${reserve_function}" == "${function_list[${index}]}" ]; then
unset function_list["${index}"]
break
fi
done
done
}
usage()
{
exit_log "Usage: ${SCRIPT_NAME} [$(get_function_list)]"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment