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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .