I have the following boilerplate for creating a shell script.
parse_debug_options()
detects non-logic options such as -h
, --help
, --trace
, or --verbose
.
It appends the rest of the options and arguments for the main logic of a script to the global _logic_args
variable.
main()
calls parse_debug_options()
first and then does set -- "${_logic_args[@]}"
to modify $@
.
I wish to eliminate global variables, especially mutable ones.
However, using set --
inside parse_debug_options()
doesn't modify the global $@
and I needed to add global _logic_args
shared between parse_debug_options()
and main()
.
Is it possible to remove _logic_args
and modify the script-wide $@
from the inside of a function?
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
declare -a _logic_args=()
function usage() {
cat <<EOF >&2
DESCRIPTION
Usage:
${0##*/} [options] [arguments]
Options:
Arguments:
Debug Options:
-h, --help Show this help message and exit
--trace Enable tracing (set -o xtrace)
EOF
}
function parse_debug_options() {
for arg in "$@"; do
case "$arg" in
-h | --help)
usage
exit 0
;;
--trace)
echo "Tracing enabled for ${0##*/}" >&2
set -o xtrace
;;
*)
_logic_args =("$arg")
;;
esac
done
}
function main() {
parse_debug_options "$@"
set -- "${_logic_args[@]}"
true
}
main "$@"
CodePudding user response:
There really isn't any way to do that; $@
is automatically local to each function.
If you want to force it, have your function emit the result to standard output, and do something like
set -- $(your function)
in the global scope.
CodePudding user response:
It's not possible to use global $@
in a function.
Alternately, I use the following code (adapted for you).
But after, I never use global "$@"
, I use global_params
variable.
#! /usr/bin/env bash
function modify_params () {
local -n local_params=$1
local -a new_local_params=()
local p=
# echo "${FUNCNAME[0]}: ${local_params[*]@A}'"
for p in "${local_params[@]}"; do
case "$p" in
-h|--help)
echo "Help"
exit
;;
-x|--trace)
echo "Tracing enabled for ${0##*/}" >&2
set -o xtrace
;;
*)
new_local_params =("${p}")
;;
esac
done
local_params=("${new_local_params[@]}")
}
declare -a global_params=("${@}")
shift $#
modify_params global_params
declare -r global_params
echo "global: ${global_params[*]@A}"