First, $((var=expr)) where you never use var is useless and misleading clutter.
Second, you don't need cat+grep+awk PLUS shell-expr for this, awk can do the whole thing:
awk </proc/meminfo '/HugePages_free/{print "Free Huge Pages in GB: " int($NF*2/1024)}'
Third, your loop can't work; you don't specify where ssh is to connect. You need something like ... do ssh -q $HOST "command"; done.
Fourth, your problem isn't actually with the loop at all, only with the ssh (remoting).
But to your question, when you give a command argument in doublequotes it is expanded for $-substitutions and backticks by your (local) shell before being given to the local program you run (here ssh, which sends that argument to the remote system to be executed there) -- and singlequotes inside the doublequotes don't alter this, while they would stop expansion if they were 'outside'. Moreover you can't put doublequotes inside doublequotes without backslashing them. Thus what you did (trimmed to be less unreadable) is:
ssh -q "export hpfgb=$((`cat-grep-awk` * 2 / 1024 )); echo "`hostname`: Free Huge Pages in GB: $hpfgb""
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
that part is executed on your _local_ system, and presumably returns 190
^^^^^^^^^^ ^^^^^^
those parts aren't even quoted, and are executed on your local system; hostname is apparently server1, and hpfgb has no value
thus what ssh gets from local shell and sends to each remote to execute is effectively
ssh -q "export hpfgb=190; echo" server1: Free Huge Pages in GB:
which you should expect to produce the result you get
Sending commands like this awk as an ssh argument is difficult because you need at least the $NF and the internal "string" if used (it could be avoided) to be quoted both in the local shell and the remote shell. It can be done, at least usually, but gets really ugly. A much simpler approach in many cases is to send the command as input to the remote shell rather than an ssh argument, such as a heredoc:
while read -u10 HOST; do ssh -q $HOST <<EOF
awk -vhost=`hostname` </proc/meminfo '/HugePages_Free/{print host ": Free Huge Pages in GB: " int($NF*2/1024)}'
EOF
done 10<list
Although something of a hack, you only need to remotely doublequote (not singlequote) the awk script if you move the literal onto the variable and put a space in the field reference:
while read -u10 HOST; do ssh -q $HOST \
'awk -vhostx=`hostname`": Free Huge Pages in GB: " </proc/meminfo "/HugePages_Free/{print hostx int($ NF *2/1024)}" '
EOF
done 10<list
Two more points:
Is it really necessary to run hostname on the remote? Its name usually should be the same as the name you connected to, and if it's different wouldn't you like to see the name you used rather than an unexpected one? I would just use $HOST instead (although in my hack method you now need to not singlequote the whole command, so this expands locally).
The while read line; do ... done <list structure (and often -r as well, which you don't have) is needed (and recommended) to correctly handle arbitrary data, but in this case we know the contents of list must be hostnames which cannot contain whitespace or glob chars. This special/limited case can be handled by the simpler:
# data limited to valid hostnames
for HOST in $(cat list); do ssh -q $HOST <EOF
as above
EOF
done
Alternatively, another general solution as long as you only need one small-enough file (i.e. don't use hostname, see above) is to do the processing locally:
while read -u10 HOST; do ssh -q $HOST cat /proc/meminfo \
| awk -vhost=$HOST '/HugePages_Free/{print host ": Free Huge Pages in GB: "int($NF *2/1024)}'
done 10<list
# only the cat runs remotely; the | awk ... is processed only by the local shell, with normal, familiar quoting