wangwang3210
wangwang3210

Reputation: 1

ssh command cannot return the result executed on remote machine

when I use ssh to execute remote file in shell script, so that I could get the result executed on remote machine, however, I met a problem which the user defined variables could not be recognized.

  1. I created a shell script run.sh like this

    #!/bin/bash
    ssh [email protected] << EOF
    ./test.sh && ret=1 || ret=0 
    echo "before" 
    echo ${ret}
    echo "after"
    echo ${HOME}
    exit ${ret}
    EOF
    
  2. the content of test.sh which is called by run.sh :

    #!/bin/bash
    echo "lala"
    exit 1
    
  3. when I call ./run.sh it print like this

    lala
    before
    
    after
    /home/jenkins
    

Why did not it echo ${ret}? After ./run.sh is called, echo $? is 0 which is unexpected, I thought it should echo 1 here. Thanks!

Upvotes: 0

Views: 854

Answers (1)

ephemient
ephemient

Reputation: 204678

Because the variables in the heredoc are being expanded by the local script before being sent to the standard input of ssh.

In other words, your heredoc behaves similarly to

#!/bin/bash
string="echo \"before\"
echo ${ret}
echo \"after\"
echo ${HOME}
exit ${ret}
./test.sh && ret=1 || ret=0"
echo "$string" | ssh [email protected]

which makes it more obvious that the string has the variables interpolated.

There are a couple ways around this: either you can escape the $ symbols (e.g. echo \${ret}) so that the intended string is passed through, or you can use a verbatim heredoc

#!/bin/bash
ssh [email protected] <<'EOF'
./test.sh && ret=1 || ret=0
echo "before"
echo ${ret}
echo "after"
echo ${HOME}
exit ${ret}
EOF

By single-quoting the delimiter, we ensure that no expansion takes place inside the heredoc.

Upvotes: 2

Related Questions