How do I pass a variable from my local server to a remote server?
Solution 1
variables are not expanded between single quotes.
use double quotes and escape the inner double quotes:
sshpass -p "password" \
ssh [email protected] "su -lc \"cp -r $location2 $location1\";"
or close the single quotes and open them again:
sshpass -p "password" \
ssh [email protected] 'su -lc "cp -r '$location2' '$location1'";'
bash does string concatenation automatically.
note: not tested. might screw up misserably if $locationX
contains spaces or other weird characters.
Solution 2
A shell variable, is just that: a variable of the shell. The ssh
command, or the shell started by sshd
on the remote host have no way to get access to that variable of the client's shell.
Exported shell variables are passed as environment variables to executed commands. So if you exported location1
it would be passed as an environment variable to ssh
. If you used the SendEnv
ssh
configuration directive (via -o
or ~/.ssh/config
or /etc/ssh/ssh_config
...), ssh
would try and send it to sshd
on the remote host.
However, for that to work, sshd
would need to have an AcceptEnv
configuration directive that allows receiving that variable. However, it's generally not the case for security reason.
Many default ssh/sshd deployment however allow passing variables whose name starts with LC_
(for localisation). So you could leverage that with:
LC_location1=$location1 LC_location2=$location2 ssh host
'su -lc '\''cp -r -- "$LC_location2" "$LC_location1"'\''
Alternatively, you could have the local shell expand the variables in the command line that is passed to the remote shell:
ssh host "su -lc 'cp -r -- $location2 $location1'"
But that's the equivalent as running:
eval eval "cp -r -- $location2 $location1"
That is those variables are not passed as arguments to cp
, they are interpreted (twice) as shell (the login shell of the remote user, and the sh
started by su
) code, so if $location1
is for instance /somewhere;rm -rf /
, that will have dramatic consequences.
The proper way would be to properly escape those for the remote shell. Because of the two levels of shells, you need to escape the single quotes twice (here using ksh93
/bash
/zsh
syntax):
escaped_location1=\'${location1//\'/\'\\\'\'}\'
escaped_location1=${escaped_location1//\'/\'\\\'\'}
escaped_location2=\'${location2//\'/\'\\\'\'}\'
escaped_location2=${escaped_location2//\'/\'\\\'\'}
ssh host "su -lc 'cp -r -- $escaped_location2 $escaped_location1'"
That assumes the login shell of the remote user is Bourne-like.
Solution 3
In addition to lesmana's answer: you should quote the variables in his second example.
sshpass -p "password" \
ssh [email protected] 'su -lc "cp -r '\\\"$location2\\\"' '\\\"$location1\\\"'";'
Related videos on Youtube
![Redson](https://i.stack.imgur.com/hCVT2.jpg?s=256&g=1)
Redson
Updated on September 18, 2022Comments
-
Redson over 1 year
I am trying to pass a variable from my local server (location1) to a remote server (location2). The purpose of the code is to copy a file from the remote server from a predefined location. In simpler terms, I want to copy files from location2 to location1 using a predefined path where location1 is on the local server and location2 is a remote server. See the code segment:
$location1=somewhere/on/local_server $location2=somewhere/on/remote_server sshpass -p "password" \ ssh [email protected] 'su -lc "cp -r $location2 $location1";'
The error I get is that both $location1 and $location2 are undefined. Also, I DON'T want to manually type the location paths because they could change at any time and it would be a pain to change them in the code if done manually.
-
arnefm about 10 yearsI am having a hard time understanding what it is you are trying to do. Are you looking for a way to transfer files between two machines? For that you can use
scp
. Example:scp remote-server:/home/Me/myfile.txt ~/Documents/
-