How to pass local variable to remote using ssh and bash script?
The variable assignment TEST="sdfsd"
given in the here document is no real variable assignment, i. e. the variable assignment will actually not be performed directly in the declaration / definition of the here document (but later when the here document gets evaluated by a shell).
In addition, the $TEST
variable contained in an unescaped or unquoted here document will be expanded by the local shell before the local shell executes the ssh
command.
The result is that $TEST
will get resolved to the empty string if it is not defined in the local shell before the ssh
command or the here document respectively.
As a result, the variable assignment export TEST="sdfsd"
in the here document will not take effect in the local shell, but first be sent to the shell of the remote host and only there be expanded, hence your prints nothing experience.
The solution is to use an escaped or single-quoted here document, <<\EOF
or <<'EOF'
; or only escape the \$TEST
variable in the here document; or just define the $TEST
variable before the ssh
command (and here document).
# prints sdfsd
export TEST="sdfsd"
ssh localhost 'bash -s' << EOF
echo $TEST
EOF
# prints sdfsd
ssh localhost 'bash -s' << EOF
export TEST="sdfsd"
echo \$TEST
EOF
# prints sdfsd
ssh localhost 'bash -s' <<'EOF'
export TEST="sdfsd"
echo $TEST
EOF
How to pass local variables to ssh scope in bash script?
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
delimiterNo 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
In Bash script trying to pass local variable to SSH and then execute the other commands
#!/bin/bash
count2=1
declare -a input
input=( "$@" )
echo " Hostname passed by user is " "${input[0]}"
HOST="${input[0]}"
while [ $# -gt $count2 ]
do
sed -i 's/VALUE/'"${input[$count2]}"'/g' ./check.sh
sshpass -p '<pass>' scp ./check.sh user@"$HOST":/home/user/check.sh
sshpass -p '<pass>' ssh -o StrictHostKeyChecking=no user@"$HOST" "sh /home/user/check.sh && rm -rf /home/user/check.sh"
sed -i 's/'"${input[$count2]}"'/VALUE/g' ./check.sh
((count2++))
done
Found the another solution of this issue: It is working for me now !!!!
I wrote my entire logic which needs to be executed remotely in check.sh
file and now replacing or storing the user input into this check.sh
file and copying this file into remote server via scp and executing it over remotely and after successful execution removing this file from remote server and after ssh , again changing the user input to it's original value in local server using sed
command.
Made this as dynamic script to work for multiple servers.
Passing variables in remote ssh command
If you use
ssh pvt@192.168.1.133 "~/tools/run_pvt.pl $BUILD_NUMBER"
instead of
ssh pvt@192.168.1.133 '~/tools/run_pvt.pl $BUILD_NUMBER'
your shell will interpolate the $BUILD_NUMBER
before sending the command string to the remote host.
Passing a variable to a remote host in a bash script with ssh and EOF
Use printf %q
to escape content in an eval
-safe form; after doing so, you can pass them on the command line of the remote shell, and retrieve them via $1
, $2
, etc. within the remote script:
# put contents of $VAR into $var_str in a format that a shell can interpret
printf -v var_str %q "$VAR"
# v- pass the value on the shell command line
# | v- keep escaping the heredoc securely
# | |
ssh -T -p 1234 root@"$host" "bash -s $var_str" <<'EOF'
# retrieve it off the shell command line
var=$1
# ...and use it as you like thereafter.
echo "Remotely using $var"
EOF
Passing variables in remote ssh command in shell script
This happens because you quote the here doc delimiter. Here's POSIX:
If any character in word is quoted, the delimiter is formed by performing quote removal on word, and the here-document lines will not be expanded. Otherwise, the delimiter is the word itself.
And here's an example:
#!/bin/bash
var=42
cat << 'end'
With quotes: $var and \$var
end
cat << end
Without quotes: $var and \$var
end
When executed:
With quotes: $var and \$var
Without quotes: 42 and $var
Related Topics
Linux: Proc/Net/Sockstat Tcp Mem More and More Larger
Can Linux Flock(Fd, Lock_Ex|Lock_Nb) Fail Spuriously
How to Execute The Vim Commands Through Shell Script
Individual Thread Priority Checking Using Command Line in Linux
Linux Async (Io_Submit) Write V/S Normal (Buffered) Write
Prevent Fork() from Copying Sockets
Error Message When Setting Up Adt in Linux
Delete Line from Text File with Line Numbers from Another File
Sdl Configuration in Eclipse Ide
Qxcbconnection: Could Not Connect to Display Aborted, When Installing Qt on Linux
Linux Patch Ignoring Line Numbers
Setting Up Sonarqube on Aws Using Ec2
Joining Line Breaks in Fasta File with Condition in Sed/Awk/Perl One-Liner
How to Convince Z/Os Scp to Transfer Binary Files