Q:

How does shell eval work?

So I wrote a script that takes an argument. The argument denotes what kind of tests to run, either qa or dev. I have the script change a value in a properties file based on the argument, originally:
dev="site1.com"
qa="site2.com"

if [ $1 == "dev" ]; 
then
   sed -i "s/site=.*/site=${dev}/g" myfile.properties
else ...

But, I changed it to:
dev="site1.com"
qa="site2.com"

eval environment=\$$1
sed -i "s/site=.*/site=${environment}/g" myfile.properties

which now makes it so I don't need an if-else structure based on the argument.
How does it work that "eval environment = \$$1" makes it so "${environment}" will actually be "${dev}" if "dev" was the argument?
In other words, using dev as the argument (sh script.sh dev)
${environment} == ${dev} rather than ${environment} == "dev"?

A:

How does eval work?
The basic way that eval works is that the arguments are treated as a command line and the command line is re-evaluated.  Quotes are re-interpreted; I/O redirection is re-interpreted; variables are re-interpreted.
Given:
eval environment=\$$1

The first pass through creates:
eval environment=$dev

The eval then interprets that as
environment=site1.com

Problem in code originally in the question
You don't put spaces around assignments in shell, even in an eval.
dev="site1.com"
qa="site2.com"

eval environment=\$$1
sed -i "s/site=.*/site=${environment}/g" myfile.properties

In Bash, you'd use:
environment=${!1}

This avoids the explicit eval, which could be dangerous if the (ab)user typed sh yourscript '$(rm -fr $HOME &)' instead of sh yourscript dev.  If you use eval, you had better carefully validate what you get to evaluate.

