The eval command line is first subject to escape and quote processing. Escape processing turns \" into ", and quote processing turns ':' into : (there's actually no need to quote this, since : has no special meaning in this context).
After this, the command that will be evaluated is:
PATH="/home/xyz/bin:$PATH"
whose meaning should be obvious.
Note that if the string you're trying to prepend contains any literal doublequote characters, the result will not work as intended. If there are an odd number you'll get a syntax error for mismatched quotes; if there are an even number they'll simply be discarded silently. E.g.
prepend PATH '/home/xyz/b"n'
results in
PATH="/home/xyz/b"n:$PATH"
The solution to this is to use the Q operator in the parameter expansion, rather than wrapping double quotes around the expansion.
prepend() { [ -d "$2" ] && eval $1=${2@Q}\":\$$1\" && export $1; }
The above prepend call results in
PATH='/home/xyz/b"n'":$PATH"
It also works correctly with embedded single quotes
prepend PATH "/home/xyz/b'n"
produces
PATH='/home/xyz/b'\''n'":$PATH"
evalbecause the variable name is dynamic.evalfor this. Tryexport "$1=$2:${!1}". See What does "${!var}" mean in shell script? for an explanation of${!1}. Also see BashFAQ/006 (How can I use variable variables (indirect variables, pointers, references) or associative arrays?). No matter how you do it you should check that$1contains a valid variable name before trying to assign to it. Otherwise bad things may happen ifprependis used incorrectly (e.g. because of a bug).