1

I've been trying several fails to perform the following:

Basically, what I need is to execute several sequenced commands on a remote unix shell, such as setting environment variables with variables that I have on the script, move to a particular directory and run a script there and so on.

I've tried using a printf with the portion of the script and then piped the ssh command, but it didn't work quite well, also, I've read about the "ssh ... >> END" marker, which is great but since I'm using functions, it doesn't work well.

Do you have any thoughts?

Here's an excerpt of the code:

deployApp() {
inputLine=$1;
APP_SPECIFIC_DEPLOY_SCRIPT="$(echo $inputLine | cut -d ' ' -s -f1)";
BRANCH="$(echo $inputLine | cut -d ' ' -s -f2)";
JBOSS_HOME="$(echo $inputLine | cut -d ' ' -s -f3)";
BASE_PORT="$(echo $inputLine | cut -d ' ' -s -f4)";
JAVA_HOME_FOR_JBOSS="$(echo $inputLine | cut -d ' ' -s -f5)";
JAVA_HEAP="$(echo $inputLine | cut -d ' ' -s -f6)";

echo "DEPLOYING      $APP_SPECIFIC_DEPLOY_SCRIPT"
echo "FROM BRANCH    $BRANCH"
echo "IN JBOSS       $JBOSS_HOME"
echo "WITH BASE PORT $BASE_PORT"
echo "USING          $JAVA_HOME_FOR_JBOSS"
if [[ -n "$JAVA_HEAP" ]]; then
    echo "WITH           $JAVA_HEAP"
fi
echo

echo "Exporting jboss to $JBOSS_HOME"
ssh me@$SERVER <<END
cleanup() {
        rm -f $JBOSS_SERVER/log/*.log
        rm -Rf $JBOSS_SERVER/deploy/
        rm -Rf $JBOSS_SERVER/tmp/
        mkdir $JBOSS_SERVER/deploy
    }

    startJboss() {
        cd $JBOSS_SERVER/bin
        ./jbossctl.sh start
        return 0;
    }
export JBOSS_HOME
export JBOSS_SERVER=$JBOSS_HOME/server/default
END
return 0;
}

With that "HERE" approach, I'm getting this error: "syntax error: unexpected end of file"

Thanks a lot in advance!

2

2 Answers 2

4

Just put the functions in your here document, too:

var="Hello World"
ssh user@host <<END
x() {
    print "x function with args=$*"
}

x "$var"
END

[EDIT] Some comments:

  1. You say "export JBOSS_HOME" but you never define a value for the variable in the here document. You should use export JBOSS_HOME="$JBOSS_HOME". BASH will take all text between the two END, replace all variables, and send the result to SSH for processing.

    That also means the other side will see rm -f /path/to/jboss/server/*.log; the assignment to JBOSS_SERVER in the last line of the here document has no effect (at least not to the code in cleanup()).

    If you want to pass $ unmodified to the remote server, you have to escape it with \: rm -f \$JBOSS_SERVER/log/*.log

  2. You never call cleanup()

  3. There is a } missing after return 0 to finish the definition of deployapp()

There may be other problems as well. Run the script with bash -x to see what the shell actually executes. You can also add echo commands in the here document to see what the values of the variables are or you can add set -x before cleanup() to get the same output as with bash -x but from the remote side.

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

6 Comments

Hi Aaron, thanks a lot for your answer! One question, though, what if that's inside another function? I've just tried and I'm still getting the "unexpected end of file" error.
Sorry, I can't debug code that I can't see. And when you post an example, don't forget the error message because my built-in bash interpreter is pretty bad. :-)
Sorry! Just posted the code and the error message I'm getting on the original post. I'm using the mentioned function at the bottom of the script along a few others.
Thanks for your updates, the missing } is right below the code portion. There are some functions that are there because I'm adapting the original code to be executed remotely... So many things don't have sense yet. Thanks a lot for your tips, I'll keep on looking. :)
To make things more simple: How about you write a script, copy that to the remote server with scp and then execute it? That way, you can avoid all the strange oddities of here documents until you get the script right. After that, you can try to convert the script to here documents. Fight one battle at a time.
|
0

I don't understand why you're using cut to split the arguments to your function. Just do

APP_SPECIFIC_DEPLOY_SCRIPT=$1
BRANCH=$2
JBOSS_HOME=$3
# etc.

If you don't quote your here document delimiter, the contents are expanded before they're sent to the server. That may be what you want. If you don't and you want all expansion to be done on the server side, then quote it like this:

ssh me@$SERVER <<'END'
# etc.
END

If you wan't a mixture, don't quote the delimiter, but do escape those things that you want delayed expansion for:

ssh me@$SERVER <<END
echo $EXPAND_ME_NOW \$EXPAND_ME_LATER
END

What are the export statements supposed to do? I can't see that they would have any effect at all.

4 Comments

I'm using cut because the arguments are being taken from a file. The exports, are setting the environment variables on the remote machine, since there will be a compilation performed there. On the other hand, I just tried what you mention about using the quotes with here, but I still get the error.
When you pass a quoted string, if you want to split it, you can do set -- $1 then use the positional parameters as I showed at the beginning of my answer. The variables you're exporting will be lost when the ssh session ends.
Thanks for the export tip, I'll have to try a different approach then... I'm now sending the commmands in the following manner: (sleep 3; echo "cd $tmpDir"; sleep 1; echo "echo > pwd";) | ssh me@$SERVER Which is basically what I've been looking for, but I'm still finding some issues...
The sleep should not be necessary.

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.