Issues with bash scripting syntax in Jenkins pipeline

54 views Asked by At

I want to perform the following script:

sh """#!/bin/bash -xe
source ${rcfile}
serverName=$(openstack server list --name openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname})
count=0
limit=6
while [ ! -z $serverName || $count -gt $limit ]
do 
  openstack server delete openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname}
  count=$((count + 1))
  sleep 10s
  serverName=$(openstack server list --name openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname})
done
if [ $count -eq $limit ]; then
  exit 1
fi
"""

Thanks in advance!

I tried using single quoted & doubly quoted and I understand for string interpolation you need doubly quotes

I know my rcfile sourcing works perfectly, as I ran this before and it works fine in a different shell block:

sh """#!/bin/bash -xe
source ${rcfile}
openstack server delete openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname}
"""

Also running this portion alone works in a shell block after souring and creating an instance with the name openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname} that pulls in the build number and current hostname succesfully (I am pulling in the build_number & hostname from a jenkins pipeline stage)

sh """#!/bin/bash -xe
source ${rcfile}
openstack server list --name openstack-cluster-smoketest-${env.BUILD_NUMBER}-${hostname}
"""
2

There are 2 answers

0
Paul Hodges On BEST ANSWER

As a habit, always paste your code into ShellCheck.net first. It will save you time and embarrassment more often than not.

Short answer - use [[ instead of [.

$: declare -i count=0 limit=3
$: while [[ -n "$serverName" ]] && (( count++ < limit )); do echo $count; done
1
2
3

or maybe

$: declare -i count=0 limit=3; while [[ -n "$serverName" && $count -lt $limit ]]; do echo $((++count)); done
1
2
3
0
yong On

I guess rcfile is a Groovy variable in your Jenkinsfile, so you use double quote for string interpolation. If this is your case, you also need to pay attention to any words starts with $ in your whole bash, like $(openstack, $serverName, $limit, they are also be interpolated if put them in double quote.

If you whole bash, only rcfile is Groovy variable, I prefer you change as following:

# set rcfile to be environment
# all variables inside global env groovy object will be injected into bash context
# as bash environment, thus you can access rcfile as $rcfile or ${rcfile},
# also access BUILD_NUMBER via ${BUILD_NUMBER}, but env.BUILD_NUMBER

env.rcfile = xxxxx

# because BUILD_NUMBER and rcfile can access as bash environment variable,
# thus no need to use double quote, single quote is right option.

sh '''
#!/bin/bash -xe

source ${rcfile}
serverName=$(openstack server list --name openstack-cluster-smoketest-${BUILD_NUMBER}-${hostname})
count=0
limit=6
while [ ! -z $serverName || $count -gt $limit ]
do 
  openstack server delete openstack-cluster-smoketest-${BUILD_NUMBER}-${hostname}
  count=$((count + 1))
  sleep 10s
  serverName=$(openstack server list --name openstack-cluster-smoketest-${BUILD_NUMBER}-${hostname})
done
if [ $count -eq $limit ]; then
  exit 1
fi
'''