1

In a bash script, what I need is to ssh to a server and do some commands, what I got so far is like this:

outPut="ss"
ssh user@$serverAddress << EOF
cd /opt/logs
outPut="$(ls -l)"
echo 'output is ' $outPut
EOF
echo "${outPut}"

But the output from terminal is:

output is  ss
ss

The output was assigned to the output from command ls -l, but what it showed is still the original value, which is ss. What's wrong here?

2 Answers 2

4

There are actually two different problems here. First, inside a here-document, variable references and command substitutions get evaluated by the shell before the document is sent to the command. Thus, $(ls -l) and $outPut are evaluated on the local computer before being sent (via ssh) to the remote computer. You can avoid this either by escaping the $s (and maybe some other characters, such as escapes you want sent to the far side), or by enclosing the here-doc delimiter in quotes (ssh user@$serverAddress << "EOF") which turns that feature off for the document.

Second, variable assignments that happen on the remote computer stay on the remote computer. There's no way for the local and remote shells to share state. If you want information from the remote computer, you need to send it back as output from the remote part of the script, and capture that output (with something like remoteOutput=$(ssh ...) or ssh ... >"$tempFile"). If you're sending back multiple values, the remote part of the script will have to format its output in such a way that the local part can parse it. Also, be aware that any other output from the remote part (including error messages) will get mixed in, so you'll have to parse carefully to get just the values you wanted.

Sign up to request clarification or add additional context in comments.

Comments

1

No, sorry that will not work.

  1. Either use command substitution value (to printf) inside the here-doc (lines bettween EOF):

    ssh user@$serverAddress << EOF
        printf 'output is %s\n' "$(ls -l /opt/logs)"
    EOF
    
  2. Or you capture the execution of command from inside ssh, and then use the value.

    outPut="$( 
        ssh user@$serverAddress << EOF
            cd /opt/logs
            ls -l
    EOF
    )"
    echo 'output is ' "$outPut"
    echo "${outPut}"
    

Option 1 looks cleaner.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.