I have a function that takes arguments in different combinations. How they are setup depends on other conditions so I created a method to set them up.
#!/bin/bash
myFunc() {
while getopts m:t::T::rp:: arg; do
case "$arg" in
m) log_msg="$OPTARG";;
t) timeout="$OPTARG";;
T) timeout_msg="$OPTARG";;
r) retry="yes";;
p) postpone="$OPTARG";;
*) die "invalid arguments $*";;
esac
done
#doStuff...
}
setupOpts() {
local name="$1"
local param="$2"
local err_msg="$3"
if someTest "$name"; then
# case all
echo "-t 9 -T "$err_msg" -p "$name" -r"
elif someOtherTest "$name" "$param"; then
echo "-t 120 -T "$err_msg" -p "$name""
else
echo "-t 300 -T "$err_msg""
fi
}
mainFunc() {
# some stuff...
opts="$(setupOpts "$someName" "$someParam" "Some Err Msg")"
myFunc -m "Some Msg" "$opts"
}
I not manage to get this working. E.g. when case all
(see comment in code) is true:
opts="$(setupOpts "peter-pan" "$someParam" "Some Err Msg")"
# -> results in: myFunc -m "some Msg" -t 9 -T "Some Err Msg" -p "peter-pan" -r
However, the arguments behind -t
and following are not parsed corretly. I guess it has something to do with quoting and word splitting.
Depending on quotes:
myFunc -m "Some Msg" "$opts"
:
timeout=9 -T "Some Err Msg" -p "peter-pan" -r
timeout_msg=
postpone=
retry=
or
myFunc -m "Some Msg" $opts
:
timeout=9
timeout_msg=Some
postpone=
retry=
Correct would be
timeout=9
timeout_msg=Some Err Msg
postpone=peter-pan
retry=yes
I have tried different other things like using escaped quotes (echo "-t 9 -T "\"Some Err Msg\"" -p "$argOne" -r"
) or using echo without surrounding quotes.
Is this somehow doable using bash or am I hitting a limit here?
PS: Setting things up in myFunc
would work as well but that's not the solution to my answer. I would like to know if this approach would work with bash somehow.
CodePudding user response:
Due to complexities of quoting, you can use nameref combined with arrays :
#!/usr/bin/env bash
myFunc() {
while getopts m:t::T::rp:: arg; do
case "$arg" in
m) log_msg="$OPTARG";;
t) timeout="$OPTARG";;
T) timeout_msg="$OPTARG";;
r) retry="yes";;
p) postpone="$OPTARG";;
*) die "invalid arguments $*";;
esac
done
#doStuff...
}
setupOpts() {
local name="$1"
local param="$2"
local err_msg="$3"
declare -n inner_opts=$4
if someTest "$name"; then
# case all
inner_opts=(-t 9 -T "$err_msg" -p "$name" -r)
elif someOtherTest "$name" "$param"; then
inner_opts=(-t 120 -T "$err_msg" -p "$name")
else
inner_opts=(-t 300 -T "$err_msg")
fi
}
mainFunc() {
# some stuff...
local outer_opts
setupOpts "someName" "someParam" "Some Err Msg" outer_opts
myFunc -m "Some Msg" "${outer_opts[@]}"
}
mainFunc
CodePudding user response:
Without the definitions of someTest
and someOtherTest
I'm unable to reproduce OP's output so fwiw ...
It looks (to me) like the setupOpts()
function generates a set of command line options that are to be passed to the myFunc()
function. Assuming setupOpts()
generates the correct output, I'm guessing one solution would be store the output from setupOpts
in an array, eg:
opts=( $(setupOpts "peter-pan" "$someParam" "Some Err Msg") )
The main call to myFunc()
then becomes:
myFunc -m "Some Msg" "${opts[@]}"