delim_to_array() {
local IFS="${2:-$' :|'}"
# eval $1\=\(${!1}\);
read -ra "$1" <<<"${!1}"
}
test="fail-test"; a="fail-test"
animal_list='anacondaanimal_list='bison, bisona space, {1..3},~/,${a},$a,$((2+2)),$(echo "fail"),./*,*,*'
delim_to_array "animal_list" ","
printf "<%s>" "${animal_list[@]}"; echo
$ so-setvar.sh
<bison>< a space>< {1..3}><~/><${a}><$a><$((2+2))><$(echo "fail")><./*><*><*>
#!/bin/bash
delim_to_array() {
local IFS="${2:-$' :|'}"
# printf "inside IFS=<%s>\n" "$IFS"
# eval $1\=\(${!1}\);
read -ra "$1" <<<"${!1}";
}
animal_list="anaconda, bison, cougar, dingo"
delim_to_array "animal_list" ","
printf "NAME: %s\n"%s\t " "${animal_list[@]}"
"; echo
people_list="alvin|baron|caleb|doug"
delim_to_array "people_list"
printf "NAME: %s\n"%s\t " "${people_list[@]}""; echo
$ ./so-setvar.sh
NAME: anaconda NAME: bison NAME: cougar NAME: dingo
NAME: alvin NAME: baron NAME: caleb NAME: doug
As the (eval) function was constructed, there is one place in which the var is exposed unquoted to the shell parsing. That allows us to get the "word splitting" done using the IFS value. But that also expose the values of the vars (unless some quoting prevent that) to: "brace expansion", "tilde expansion", "parameter, variable and arithmetic expansion", "command substitution", and "pathname expansion", In that order. And process substitution <() >() in systems that support it.
a=failed; echo {1..3} ~/ ${a} $a $((2+2)) $(ls) ./*
If you are sure that the variables do not contain such problematic values, thethen you are safe. If there is the potential to have such values, the ways to answer your question are more complex and need more (even longer) descriptions and explanations. Using read is an alternative.
- Always use the -r option, it is very hard for me to think of a condition where it is not needed.
- The
readcommand could get only one line. No multiple lines valuesMulti-lines, even by setting the (ok in 99% of cases)-doption, need special care. Or the whole input will be assigned to one variable. - If
IFSvalue contains an space, leading and trailing spaces will be removed. Well, the complete description should include some detail about thetab, but I'll skip it. - Do not pipe
|data to read. If you do, itread will be in a sub-shell. All variables set in a sub-shell do not workpersist upon returning to the parent shell. Well, there are some workarounds, but, again, I'll skip the detail.