> On 10 Jun 2013 14:15, "Chris F.A. Johnson" <ch...@cfajohnson.com> wrote: > > It is not the least bit difficult with eval: > > > > eval "array=( \"\${$1[@]}\" )"
On Mon, Jun 10, 2013 at 09:17:23PM +0800, Chris Down wrote: > Enjoy your arbitrary command execution. To be fair, Chris Johnson was probably assuming a programming environment where the function is only callable from within the same script, and thus has only trustworthy arguments provided by the caller. Sometimes, this is the case. Sometimes, it isn't. In a more general sense, using eval SAFELY requires undergoing several tedious steps, all of which were brushed aside as "not the least bit difficult", which is certainly an exaggeration. 1) Figure out what command you would want to execute if you had the actual array name in front of you right now: arrayname[i++]="$foo $bar" 2) Escape all the metacharacters in such a way that you can stick it inside double quotes without mangling anything: arrayname[i++]=\"\$foo \$bar\" 3) Figure out where the arrayname is going to come from, and whether it is trustworthy (or "untainted" if you prefer perl's wording). If it is untrustworthy (tainted) then you'll either need to run it through printf %q, or check it for invalid characters and abort if found, depending on the needs of the program. local aref printf -v aref %q "$1" 4) Replace the "arrayname" placeholder in the escaped command: $aref[i++]=\"\$foo \$bar\" 5) Wrap eval "..." around it. All together: local aref printf -v aref %q "$1" eval "$aref[i++]=\"\$foo \$bar\"" To call this "not the least bit difficult" strikes me as somewhat disingenuous. But I'll concede that it is certainly *possible*, albeit only with the use of bash's printf %q extension. It is not possible to do this safely in strict POSIX shells, other than by searching the input for invalid characters and aborting.