How have both local and remote variable inside an SSH command

How can I have both local and remote variable in an ssh command? For example in the following sample code:

A=3;
ssh host@name "B=3; echo $A; echo $B;"

I have access to A but B is not accessible.

But in the following example:

A=3;
ssh host@name 'B=3; echo $A; echo $B;'

I don't have A and just B is accessible.

Is there any way that both A and B be accessible?


Solution 1:

I think this is what you want:

A=3;
ssh host@name "B=3; echo $A; echo \$B;"

When you use double-quotes:

Your shell does auto expansion on variables prefixed with $, so in your first example, when it sees

ssh host@name "B=3; echo $A; echo $B;"

bash expands it to:

ssh host@name "B=3; echo 3; echo ;"

and then passes host@name "B=3; echo 3; echo ;" as the argument to ssh. This is because you defined A with A=3, but you never defined B, so $B resolves to the empty string locally.


When you use single-quotes:

Everything enclosed by single-quotes are interpreted as string-literals, so when you do:

ssh host@name 'B=3; echo $A; echo $B;'

the instructions B=3; echo $A; echo $B; will be run once you log in to the remote server. You've defined B in the remote shell, but you never told it what A is, so $A will resolve to the empty string.


So when you use \$, as in the solution:

\$ means to interpret the $ character literally, so we send literally echo $B as one of the instructions to execute remotely, instead of having bash expand $B locally first. What we end up telling ssh to do is equivalent to this:

ssh host@name 'B=3; echo 3; echo $B;'