DISCLAIMER. English language used here only for compatibility (ASCII only), so any suggestions about my bad grammar (and not only it) will be greatly appreciated.

воскресенье, 8 мая 2011 г.

Variable assignment in bash `eval`

Here is example of variable assignment in eval:

    (
        v="a\" b";
        eval "r=\"$v\"";
        declare -p r
    )

Such assignment lead to error due to unmatched double quote. Here is corrected
version of above example

    (
        v="a\" b";
        eval "r=\"\$v\"";
        declare -p r
    )

And here is example of executing arbitrary command through such incorrect eval
construction:

    (
        v="a\"; ls; \":";
        eval "r=\"$v\"";
        declare -p r
    )

Note a colon (':') in 'v' value: bash does not even complain about incorrect
syntax - all is correct and all will work fine!

So, it's safe (perhaps) to use parameter expansion to form variable's name for
assign to, like

    (
        v="arr";
        eval "${v}[1]=123";
        declare -p arr;
        eval "r=\${${v}[1]}";
        declare -p r
    )

because here bash's own constrains on characters in variable name applied, and
bash checks this. But it's _not_ safe to expand variable up to value in the
main script - do it in eval script instead.

Note, the same also applies to indirect reference: do not use it to expand up
to value in main script in eval constructions. Here is flawed example:

    (
        j=var;
        var="a\"; ls; \":";
        i=r;
        eval "$i=\"${!j}\"";
        declare -p r;
    )

and now corrected version

    (
        j=var;
        var="a\"; ls; \":";
        i=r;
        eval "$i=\"\${$j}\"";
        declare -p r;
    )

or with indirect reference

    (
        j=var;
        var="a\"; ls; \":";
        i=r;
        eval "$i=\"\${!j}\"";
        declare -p r;
    )