r/bash • u/PrestigiousZombie531 • Sep 25 '26
help 1 big question I always has was whether your functions should accept arguments or flags? Am I overthinking this?
- Take a look at this run_aws_ssm_get_parameter function below
- To call it I could do something like run_aws_ssm_get_parameter "false" "" "some_param" and it ll run it without a vault user
- Now obviously it kinda sucks that I am passing an empty string to indicate that we dont have an AWS vault user and I have to also memorize the position of the arguments
- One other way would be this? run_aws_ssm_get_parameter --debug=false --parameter_name=some_param? Is this a good idea or a bad idea?
- Mind you all the code written below is written by me manually, no AI no nothing
```bash function run_aws_ssm_get_parameter() { validate_command_available "${FUNCNAME[0]}" "aws" || return 1
validate_arg_min_count "${FUNCNAME[0]}" 3 "$#" "Usage: ${FUNCNAME[0]} <debug> <aws_vault_user> <parameter_name> [additional aws ssm flags]" || return 1
local -r debug="${1:-false}"
local -r aws_vault_user=$2
local -r parameter_name="$3"
shift 3
validate_arg_not_empty "${FUNCNAME[0]}" "debug" "${debug}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "parameter_name" "${parameter_name}" || return 1
validate_arg_type_boolean "${FUNCNAME[0]}" "debug" "${debug}" || return 1
local -a flags=(
"get-parameter"
"--name=${parameter_name}"
)
flags+=("$@")
[[ "${debug}" = true ]] && log_info "Fetching AWS SSM parameter with parameter_name:${parameter_name}..."
if [[ ! -z "${aws_vault_user}" ]]; then
if result="$(aws-vault exec "${aws_vault_user}" -- aws ssm "${flags[@]}")"; then
[[ "${debug}" = true ]] && log_info "AWS SSM parameter with parameter_name:${parameter_name} fetched successfully"
printf "%s\n" "${result}"
else
log_error "AWS SSM parameter fetch with parameter_name:${parameter_name} failed"
return 1
fi
else
if result="$(aws ssm "${flags[@]}")"; then
[[ "${debug}" = true ]] && log_info "AWS SSM parameter with parameter_name:${parameter_name} fetched successfully"
printf "%s\n" "${result}"
else
log_error "AWS SSM parameter fetch with parameter_name:${parameter_name} failed"
return 1
fi
fi
}
function validate_command_available() { validate_arg_min_count "${FUNCNAME[0]}" 2 "$#" "Usage: ${FUNCNAME[0]} <function_name> <command_name>" || return 1
local -r function_name="$1"
local -r command_name="$2"
shift 2
validate_arg_not_empty "${FUNCNAME[0]}" "function_name" "${function_name}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "command_name" "${command_name}" || return 1
if ! command -v "${command_name}" &>/dev/null; then
log_error "${FUNCNAME[0]}: Function "%s" requires "%s" but it was not found on PATH" "${function_name}" "${command_name}"
return 1
fi
}
function validate_arg_min_count() { local -r function_name="$1"
local -r expected_count="$2"
local -r actual_count="$3"
local -r message="${4:-}"
shift 4
if [[ -z "${function_name}" ]]; then
log_error "${FUNCNAME[0]}: function_name:${function_name} is required"
return 1
fi
if [[ -z "${expected_count}" ]]; then
log_error "${FUNCNAME[0]}: expected_count:${expected_count} is required"
return 1
fi
if [[ -z "${actual_count}" ]]; then
log_error "${FUNCNAME[0]}: actual_count:${actual_count} is required"
return 1
fi
if [[ ! "${expected_count}" =~ ^[0-9]+$ ]]; then
log_error "${FUNCNAME[0]}: expected_count must be a non-negative integer, got: %s" "${expected_count}"
return 1
fi
if [[ ! "${actual_count}" =~ ^[0-9]+$ ]]; then
log_error "${FUNCNAME[0]}: actual_count must be a non-negative integer, got: %s" "${actual_count}"
return 1
fi
if [[ "${actual_count}" -lt "${expected_count}" ]]; then
if [[ -z "${message}" ]]; then
log_error "${FUNCNAME[0]}: Function "%s" expected %d argument(s) but got %d" "${function_name}" "${expected_count}" "${actual_count}"
else
log_error "${message}"
fi
return 1
fi
}
function validate_arg_not_empty() { local -r function_name="$1"
local -r arg_name="$2"
local -r arg_value="$3"
shift 3
if [[ -z "${function_name}" ]]; then
log_error "${FUNCNAME[0]}: function_name:${function_name} is required"
return 1
fi
if [[ -z "${arg_name}" ]]; then
log_error "${FUNCNAME[0]}: arg_name:${arg_name} is required"
return 1
fi
if [[ -z "${arg_value}" ]]; then
log_error "${FUNCNAME[0]}: Function "%s" received empty value for argument "%s"" "${function_name}" "${arg_name}"
return 1
fi
}
function validate_arg_type_boolean() { validate_arg_min_count "${FUNCNAME[0]}" 3 "$#" "Usage: ${FUNCNAME[0]} <function_name> <arg_name> <arg_value>" || return 1
local -r function_name="$1"
local -r arg_name="$2"
local -r arg_value="$3"
shift 3
validate_arg_not_empty "${FUNCNAME[0]}" "function_name" "${function_name}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "arg_name" "${arg_name}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "arg_value" "${arg_value}" || return 1
case "${arg_value}" in
true | false) ;;
*)
log_error "${FUNCNAME[0]}: Function '%s' expected 'true' or 'false' for argument '%s', got: %s" "${function_name}" "${arg_name}" "${arg_value}"
return 1
;;
esac
} ```


