1

I have a 'problem' with a script I'm developing in HP-UX KSH. The script contains many functions, and I need to pass the same set of parameters between them. All well and good, but some parameters can be blank. Its easy to pass blank parameters using double double-quotes (""), but what if I want to pass a complete set of parameters from one function into another using ${@}, including blanks? And to make things tricky, there can be a variable number of parameters each time, so the method has to be dynamic.

Example: I've got a function called test1 that takes a number of parameters. Any of them can be blank. I've also created a function called test2 into which all the parameters of test1 are passed:

test1()
{
  echo 1-1: ${1}
  echo 1-2: ${2}

  test2 ${@}
}

test2()
{
  echo 2-1: ${1}
  echo 2-2: ${2}
}

# test1 "" hello

1-1:
1-2: hello
2-1: hello
2-2:

The trouble is, if ${1} is blank, ${2} from test1 appears as ${1} in test2. So to work around the problem I created this code, which effectively creates a function string with all parameters surrounded with double quotes:

test1()
{
  typeset var FUNC="test2"
  typeset -i var COUNT=1

  echo 1-1: ${1}
  echo 1-2: ${2}

  while [ ${COUNT} -le ${#@} ]; do
    typeset var PARAM=$(eval "echo \$${COUNT}")
    FUNC="${FUNC} \"${PARAM}\""
    ((COUNT=COUNT+1))
  done

  eval "${FUNC}"
}

# test1 "" hello

1-1:
1-2: hello
2-1: 
2-2: hello

This works very nicely, thank you. Now to my 'problem'.

Is it actually possible to encapsulate the above code in a function of its own? It seems a catch 22 to me, in that you have to run that code to pass the blank parameters. I have to repeat this code snippet many times in my script because I can't find another way. Is there one?

Any help or guidance will be gratefully received.

FenderBender
  • 11
  • 1
  • 4
  • 1
    Double quotes! Use `"$@"`, not `${@}`. Tooting my own horn a bit, see https://stackoverflow.com/q/12314451/7552 . See also [Security implications of forgetting to quote a variable in bash/POSIX shells](https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells) – glenn jackman May 31 '18 at 18:47
  • Blimey, was it really that simple?? Doh! Thanks. – FenderBender May 31 '18 at 19:57
  • Actually, I still have to use the code because I'm calling another function using eval, and that doesn't resolve the blank parameters even with "$@". So I still need the loop but only in one location, so it's still a good result. Thanks! – FenderBender Jun 01 '18 at 07:09
  • You should not have to use eval anywhere. Quote your variables and that should resolve it. See this page to help you drop eval: [I'm trying to put a command in a variable, but the complex cases always fail!](http://mywiki.wooledge.org/BashFAQ/050) – glenn jackman Jun 01 '18 at 14:49
  • 1
    Thanks. I see where you're coming from. Perhaps I overthought the problem. In my second example, I can reduce _eval "${FUNC}"_ to simply _"${FUNC}" "${@}"_ – FenderBender Jun 02 '18 at 18:14

1 Answers1

0

Here is how I would write your functions:

show_params() {
    typeset funcname=$1
    typeset -i n=0
    shift
    for arg; do 
        ((n++))
        printf "%s:%d >%s<\n" "$funcname" $n "$arg"
    done
}
test1() { show_params "${.sh.fun}" "$@"; test2 "$@"; }
test2() { show_params "${.sh.fun}" "$@"; }

test1 "" 'a string "with double quotes" in it'
test1:1 ><
test1:2 >a string "with double quotes" in it<
test2:1 ><
test2:2 >a string "with double quotes" in it<

Using your definition of test1, which builds up a string containing a command, adding double quotes around all the paramers, and then eval-ing the string, I get this result

$ test1 "" 'a string "with double quotes" in it'
1-1:
1-2: a string "with double quotes" in it
test2:1 ><
test2:2 >a string with<
test2:3 >double<
test2:4 >quotes in it<

That's because you're doing this:

eval "test2 \"\" \"a string \"with double quotes\" in it\""
# ......... A A  A          B                   B       A
# A = injected quotes
# B = pre-existing quotes contained in the parameter
glenn jackman
  • 238,783
  • 38
  • 220
  • 352