How to have local shell variables in a ksh script seen on remove server in SSH block?

I have googled this and found many solutions, but none of them are working for me. I am in a korn shell, most others reference bsh, maybe that is the issue? Anyway, all I am trying to do is use a variable I have declared in my main script in a remote shell I am running through ssh.

So I have a script with code similar to this:

filepath=/xxx/yyy/zzz/
filename=xyz

ssh uid@hostname << 'ENDSSH'
.
.
if [[ -e ${filepath}${filename} ]]; then
....
....
fi

ENDSSH

But filepath and filename are blank in the remote shell as they are declared locally. How do I get those values seen in the SSH block?

either:

filepath=/xxx/yyy/zzz/
filename=xyz

ssh uid@hostname << ENDSSH
.
.
if [[ -e \${filepath}\${filename} ]]; then
....
....
fi

ENDSSH

or

filepath=/xxx/yyy/zzz/
filename=xyz

ssh -q uid@hostname " \
. \
. \
myRemoteVar='foo' \
echo here's my remoteVar->[\${myRemoteVar}] \
if [[ -e ${filepath}/${filename} ]]; then
.... \
.... \
fi " < /dev/null

# the \${vars} are variables to be evaluated on the REMOTE host

Thanks but these don't work. Escaping the variables with a backslash does nothing - tried in double quotes also as in \"$var" and either way they are still blank in the SSH block. If I just say

fn=\$filename 
or
fn=\"$filename"

and then echo $fn right afterwards either way it is blank.

I'm not really sure what you are trying to show in the second one. Yes I can declare a variable within the SSH part and use it there, but that doesn't help me. I need to be able to reference the variables I declared before I accessed the remote server.

--- Post updated at 09:18 AM ---

I've been playing around with it some more and here is something I've found that really stumps me. As I said, escaping it with the backslash does nothing. However if I use double quotes ONLY, it does, sort of:

If I say within the SSH block,

echo fp = $\filepath

It returns nothing: fp =

However if use doublequotes:
echo fp = "$filepath"

This works, it displays fp = /xxx/yyy/zzz/

However, it still won't assign it to a local variable or work in an expression. So if I try this:

echo fp = "$filepath"
fp="$filepath"
echo fp = $fp

I get

fp = /xxx/yyy/zzz/
fp = 

Why is it that i can evaluate it in the echo statement but it won't assign it to the remote variable?

DJR,
this is not what I suggested and not how to assign/use/display local vs remote vars - please reread my original post.

filepath=/xxx/yyy/zzz/
filename=xyz

ssh -q uid@hostname " \
. \
. \
myRemoteVar='foo' \
echo here's my remoteVar->[\${myRemoteVar}] \
if [[ -e ${filepath}/${filename} ]]; then
.... \
.... \
fi " < /dev/null

# the \${vars} are variables to be evaluated on the REMOTE host

I think that code in unquoted here documents is problematic: too many levels of quoting.
In zsh you can chain two (or more) redirections

#!/bin/zsh
filepath=/xxx/yyy/zzz/
filename=xyz

ssh uid@hostname << EOT1 << 'ENDSSH'
filepath=$filepath
filename=$filename
EOT1
.
.
if [[ -e ${filepath}${filename} ]]; then
....
....
fi

ENDSSH

The first part EOT1 is unquoted and assigns the local variables to the remote variables.
Instead of directly feeding the login shell (where ssh might complain that a tty is missing) it is more correct to run an explicit /bin/sh (or /bin/bash)

ssh uid@hostname /bin/sh -s << EOT1 << 'ENDSSH'

Having this, with any standard shell you can pass the local variables as parameters

filepath=/xxx/yyy/zzz/
filename=xyz

ssh uid@hostname /bin/sh -s $filepath $filename << 'ENDSSH'
filepath=$1
filename=$2
.
.
if [[ -e ${filepath}${filename} ]]; then
....
....
fi

ENDSSH
2 Likes

Thank you for that MadeinGermany. The first way didn't work (maybe because I'm using korn shell) but the second one using /bin/sh -s $filepath $filename << 'ENDSSH ' did the trick.

So now I can not figure out how to return a value from within this SSH block. So as in the above discussion I can pass parameters from my local machine to the commands running on a remote machine via ssh:

filepath=/xxx/yyy/zzz/
filename=xyz

ssh uid@hostname /bin/sh -s $filepath $filename << 'ENDSSH'
filepath=$1
filename=$2
.
.
if [[ -e ${filepath}${filename} ]]; then
....
....
fi

ENDSSH

Now I want to send a return code or messages that are produced on that remote machine and get those values back onto my local server where the code is running to decide what to do based on success or not on the remote server. I've searched and not found a solution that works to do this. (this is a korn shell by the way) How can I get variable values back from within that ENDSSH block?

To get values back you'll have to print them and retrieve them in $( ) brackets.

VALUE=$(ssh username@host -s var1 var2 <<EOF
...
echo $VALUE
EOF
)

echo "Remote host sent VALUE=$VALUE"

The return or exit code of the entire ssh construct is the one of the last command executed, so use it like you do with local ones.

You can use "command substitution", echo a remote variable, and assign its output to a (one) variable, eventually an array:

VARLOC=$(ssh .... echo ...)

Or, you can read several variables from a redirected "here document" or "here string" containing the "command substitution":

read VARA VARB VARC REST <<< $(ssh ... )