0

Context: I have a task to run a few script on a remote machine, and exit

I have a script, but I am confused how to use the line break inside it,

triggerPerformanceTest(){
report=$1
userDataFiles=$2
baseURL=$3
cdnURL=$4
streamingURL=$5
echo "Startin the Jmeter script"
ssh -tt -i Test.ppk username@<test server> <<EOF
cd apache-jmeter-3.1/bin/
JVM_ARGS="-Xms512m -Xmx25000m" ./jmeter.sh -n -t /home/ubuntu/JMeter/Test.jmx --jmeterproperty XMLReport=$report --jmeterproperty UserDataFile=$userDataFiles --jmeterproperty BaseUrl=$baseURL --jmeterproperty CdnUrl=$cdnURL --jmeterproperty StreamingUrl=$streamingURL --jmeterproperty isBenchMark=false --jmeterproperty Enable_DigitalExhaust=true --jmeterproperty Enable_Health=true --jmeterproperty HealthPollingInterval=6
exit
EOF
echo "Test successfully executed"
}

triggerPerformanceTest Log.csv UserDataFile.csv localhost localhost localhost

In step two, where I am running the JMeter script, it has a lot of properties. Is there a way I can use a line break here, so it will consider all the lines to be in one step. Like mentioned below

ssh user@server << EOF
  command_one
  command_two argument1 argument2 argument3 argument4
              argument5 argument6 argument7
  command_three
EOF

2 Answers 2

8

Inside here documents where the delimiter after << (here EOF) is not quoted, the <backslash><newline> sequence is removed, that's a line continuation.

Actually, the only cases where <backslash><newline> is not removed is:

  • inside single quotes
  • inside here documents where the delimiter is quoted
  • where the backslash itself is quoted (<backslash><backslash><newline>)

cat << EOF
foo\
bar
EOF

outputs

foobar

So, here you can do:

ssh user@server << EOF
  command_one
  command_two argument1 argument2 argument3 argument4 \
              argument5 argument6 argument7
  command_three
EOF

And ssh will end up being fed:

  command_one
  command_two argument1 argument2 argument3 argument4               argument5 argument6 argument7
  command_three

On its stdin.

Even if you used: ssh ... << 'EOF' so as to avoid parameter expansion, command substitution and arithmetic expansion being performed inside the here-document, ssh would be fed:

  command_one
  command_two argument1 argument2 argument3 argument4 \
              argument5 argument6 argument7
  command_three

But the remote shell would interpret that <backslash><newline> as a line continuation, so it would have the same effect.

Note that when you do:

ssh user@server << EOF

sshd on the remote host runs the user's login shell to interpret that code. Since it could be anything, not necessarily a Bourne-like shell, it may be better to run:

ssh user@server sh << EOF

Where sshd runs user-s-login-shell -c sh, so you know a Bourne-like shell is interpreting your code.

As an example that JVM_ARGS="-Xms512m -Xmx25000m" ./jmeter.sh... is Bourne-shell or compatible syntax. It would work in csh, tcsh, rc, es, fish shells, so wouldn't work with ssh user@server sh << EOF if the login shell of user on server was one of those shells.

A significant difference though is that in that case, user-s-login-shell is not started as a login shell so won't read /etc/profile or ~/.profile (or the equivalent for the user's login shell) to set the login session up.

Alternatively, you could convert that code to a syntax compatible to all those shells: env JVM_ARGS='-Xms512m -Xmx25000m' ./jmeter.sh... (use single quotes instead of double quotes and use env to pass an env var instead of the Bourne/rc specific envvar=value cmd syntax).

The backslashes can be avoided by using xargs:

ssh user@server sh << EOF
  command_one
  xargs command_two << END_OF_ARGS
    argument1 argument2 argument3 argument4
    argument5 argument6 argument7
  END_OF_ARGS
  command_three
EOF

Or by using a shell like rc, ksh93, zsh, bash, yash and an array:

With rc/zsh syntax:

ssh user@server zsh << 'EOF'
  command_one
  args=(
    argument1 argument2 argument3 argument4
    argument5 argument6 argument7
  )
  command_two $args
  command_three
EOF

(here quoting EOF so that $args is not expanded by the local shell).

Or with the ksh93/bash/yash syntax (also works with zsh):

ssh user@server bash << 'EOF'
  command_one
  args=(
    argument1 argument2 argument3 argument4
    argument5 argument6 argument7
  )
  command_two "${args[@]}"
  command_three
EOF
0
1

Yes end lines with a \ to continue on next line.

ssh user@server << EOF
  command_one
  command_two argument1 argument2 argument3 argument4\
              argument5 argument6 argument7
  command_three
EOF
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.