This is a very "popular" topic on stackoverflow and unfortunately I haven't been able to figure this out when looking at other questions. Anyways let's consider the following scenario.
A function gets a bunch of string arguments like so:
some_function "give some" "string arguments"
The first thing this function does is put these args into an array so that for example array[0] gives "give some" and array[1] gives "string arguments"
Now lets say I have an array of strings some_array
and want to call some_function on it. How do I "transform" that array to make it work?
Here are a few examples which do NOT work:
function print_args() {
local arr=( "$@" )
i=0;
for item in "${arr[@]}"
do
echo "[$i] -> '$item'"
(( i++ ))
done
}
echo "example"
print_args "this is" "the desired" "behavior"
echo -e "----------------\n"
some_array=( "\"does NOT\"" "\"seem to\"" "\"work\"" )
stringified_array=$(printf "%s " "${some_array[@]}")
echo "stringified array: [$stringified_array]"
echo "1) passing \$some_array"
print_args $some_array
echo -e "---------------------------\n"
echo "2) passing \"\$some_array\""
print_args "$some_array"
echo -e "---------------------------\n"
echo "3) passing \$stringified_array"
print_args $stringified_array
echo -e "---------------------------\n"
echo "4) passing \"\$stringified_array\""
print_args "$stringified_array"
echo -e "---------------------------\n"
and here is the output
example
[0] -> 'this is'
[1] -> 'the desired'
[2] -> 'behavior'
----------------
stringified array: ["does NOT" "seem to" "work" ]
1) passing $some_array
[0] -> '"does'
[1] -> 'NOT"'
---------------------------
2) passing "$some_array"
[0] -> '"does NOT"'
---------------------------
3) passing $stringified_array
[0] -> '"does'
[1] -> 'NOT"'
[2] -> '"seem'
[3] -> 'to"'
[4] -> '"work"'
---------------------------
4) passing "$stringified_array"
[0] -> '"does NOT" "seem to" "work" '
---------------------------
I think I understand 1) and 2) and only tried them out of desperation. I believe I understand 4) as well. Now my big problem is that I don't understand what the heck is going on with 3) and more importantly how I can "stringify" my array so as to achieve what I want. An important note here is that I would like to try and avoid the use of eval
.
Thanks!
You may expect that you are saying with 3):
but in reality 3) is equivalent to:
this is because the unquoted argument variable
$stringified_array
is split into words onIFS
before it is passed to the function. The double quotes within the string is just a part of string and does not work to quote the whitespaces.Try to see what happens by modifying line #16-#17 in your sample code with:
By assigning
IFS
to a delimiter which does not appear in your strings, you will be able to stringify your array safely, although there will be other solutions without stringifying the array.Hope this helps.