Array with String Elements

How can I get my array to understand the double-quotes I'm passing into it are to separate text strings and not part of an element? here's what I'm working with...

db2 -v connect to foo

db2 -x "select '\"' || stats_command || '\",' from db2law1.parallel_runstats where tabname = 'BAZ'"
set -A runstatCmds `db2 -x "select '\"' || stats_command || '\"' from db2law1.parallel_runstats where tabname='BAZ'"`

echo "Number of array variables: ${#runstatCmds[@]}"
echo "First array variable: ${runstatCmds[0]}"
echo "Second array variable: ${runstatCmds[1]}"


set -A strings "foo bar" "boo far"
echo "First array variable: ${strings[0]}"
echo "Second array variable: ${strings[1]}"

db2 terminate

and the output is...

schmitty@prep001a:
/home/schmitty/tmp> sh unixpost.sh
connect to foo

   Database Connection Information

 Database server        = DB2/AIX64 9.1.7
 SQL authorization ID   = SCHMITTY
 Local database alias   = FOO


"runstats on table CD.BAZ with distribution and detailed indexes all allow write access",       
"runstats on table SCHMITTY.BAZ with distribution and detailed indexes all allow write access",   
Number of array variables: 26
First array variable: "runstats
Second array variable: on
First array variable: foo bar
Second array variable: boo far
DB20000I  The TERMINATE command completed successfully.

So what I'm looking to do is dynamically populate the array with the value of the query but I can't seem to get the array to handle the quoting properly.

If I understood your situation correctly, I believe the solution is to use eval to pass the result of the command substitution though the shell's parser.

I'm using an old version of bash which does not support "set -A", so I'm using positional parameters instead of an array variable to try and explain myself. The principles involved are identical. Hopefully, I am able to get my point across :slight_smile:

$cat eval.sh
# The goal is to assign the value of $first to $1
# and the value of $second to $2.

first='$second'  second='boo far'

# 1)
# This first example exhibits the problem you are
# experiencing.  The quotes intended to delimit the
# string are taken as part of the string itself,
# since command substitution occurs after the parsing
# step which cares about quoting.

set -- `echo \"$first\" \"$second\"`
echo "First positional parameter: $1"
echo "Second positional parameter: $2"

# Outputs:
# First positional parameter: "$second"
# Second positional parameter: "boo

# -----------------------------------------

# 2)
# Adding eval passes the result from command substitution
# through the parser, and the quotes are indeed interpreted
# as you'd like.  However, with weak double quotes, if
# there is anything in the substituted text that would
# cause the shell to attempt parameter/command substitution,
# the output will be undesirably affected. In this case, the
# value of $first, the string "$second", is taken as a parameter
# which is then substituted, resulting in the value of $1 
# being identical to that of $2.

eval set -- `echo \"$first\" \"$second\"`
echo "First positional parameter: $1"
echo "Second positional parameter: $2"

# Outputs:
# First positional parameter: boo far
# Second positional parameter: boo far

# -----------------------------------------

# 3)
# The correct solution is wrap the command substituted values
# in strong quotes, to ensure that they are taken literally and
# not word split when passed through the parser a second time.

eval set -- `echo \'$first\' \'$second\'`
echo "First positional parameter: $1"
echo "Second positional parameter: $2"

# Finally, the correct output:
# First positional parameter: $second
# Second positional parameter: boo far

Hope this helped,
alister

set -A strings '"foo bar"' '"boo far"'
strings=("\"foo bar\"" "\"boo far\"")
strings=("\"$(some cmd)\"" "\"boo far\"")

Somehow I completely missed the output section of your post, until after I had typed and submitted my earlier post. Perhaps the following will suffice:

eval set -A runstatCmds `db2 -x "select '\"' || stats_command || '\"' from db2law1.parallel_runstats where tabname='BAZ'" | tr -d ,`

That may be good enough, but if you wanted to be very cautious, changing the double quotes to single quotes would be a good idea. Double quoting the command substitution would preserve whitespace, but the embedded newline which seems to be in the db2 output would then cause problems with eval. A workaround for that would be to use tr to convert it to a space.

Take care,
alister

Simple enough - add the 'eval' before the 'set -A' and all is well. Thanks :b: