Steeve007 Steeve007 - 2 months ago 17
Linux Question

How to pass local variables to ssh scope in bash script?

I am writing the bash script, which has to perform some of the commands on remote server via ssh. The script has two major parts:

Part 1:
Using local variables $A and $B

Part 2:
Execute commands on remote server as follows:


ssh -T user@servername << 'EOF'
...
Using local variables $A and $B
...
EOF


The problem is that local variables $A and $B are not available within scope of ssh commands on remote server. As far as I understand the variables $A and $B outside and within ssh scope are not the same.

So my question is how to pass local variables from bash script to ssh scope?
One more note, the part 2 is pretty big so I can't use "one liner" after ssh.

Thanks

Answer

The problem has nothing to do with ssh but is only related to here documents in bash or any other Posix shell.

Man page for bash says in the here document paragraph:

The format of here-documents is:

<<[-]word
here-document
delimiter

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and ` .

As you quote EOF, you explicitely ask the shell not to replace the $1 and $2 variables.

The most robust way is to not quote EOF and consistently quote all others special characters in the here document.

For example, if your here document contained something like:

ssh -T user@servername << 'EOF'
for f in /var/log/messages*
do echo "Filename: " $f
done
EOF

you could rewrite it with no quotes around EOF but with one inside $:

ssh -T user@servername << EOF
for f in /var/log/messages*
do echo "Filename: " \$f
done
EOF

That way all unquoted varibles would be interpolated.


Alternatively, if the server allows it, you can try to pass the 2 parameters as environment variables.

Say you want to use the names PARAM1 and PARAM2. The sshd_config file on the server should contain the line AcceptEnv PARAM1 PARAM2 because by default and for security reasons no environment variable is accepted.

You can then use:

export PARAM1=$1
export PARAM2=$2
ssh -T -o SendEnv=PARAM1 -o SenEnv=PARAM2 user@servername  << 'EOF'
...
Using variables $PARAM1 and $PARAM2
...
EOF