3

Below is a script I am running in the deploy of a docker container. The docker ps -a | grep $APP_CONTAINER_NAME command is returning non-zero when the container was not correctly built/tested, hence the || true.

How can I prevent Jenkins from interpreting the ${PIPELINESTATUS[0]} as a variable replacement in the script?

sh label: 'Stop and Remove Old Docker Container', script: '''
                    docker ps -a
                    echo $APP_CONTAINER_NAME

                    docker ps -a | grep $APP_CONTAINER_NAME || true
                    DOCKERCODE="${PIPESTATUS[0]}"
                    GREPCODE="${PIPESTATUS[1]}"
                    echo "Docker Command Code: $DOCKERCODE"

                    echo "Grep Command Code: $GREPCODE"

                    if [ $DOCKERCODE -eq 0 ] then;
                        docker stop $APP_CONTAINER_NAME
                        docker rm $APP_CONTAINER_NAME
                    else
                        echo "WARNING: Docker command was empty or had an error"
                    fi
                '''

EDIT1: To clarify - this command gives the error /mnt/data/jenkins/workspace/Test@tmp/durable-4c7b4748/script.sh: 7: /mnt/data/jenkins/workspace/Test@tmp/durable-4c7b4748/script.sh: Bad substitution

I've tried triple double quotes, escaping the quotes in the shell script, and single quoting the PIPESTATUS command prevents execution.

UPDATE: I tried escaping quite a few things. A single slash results in the above error as well. A double slash results in printing the line and not running the bash command.

        sh label: 'Stop and Remove Old Docker Container', script: '''
                docker ps -a
                echo $APP_CONTAINER_NAME

                docker ps -a | grep $APP_CONTAINER_NAME || true
                echo "HERE"
                echo \\${PIPESTATUS[@]}
                DOCKERCODE="\\${PIPESTATUS[0]}"
                GREPCODE="\\${PIPESTATUS[1]}"
                echo "Docker Command Code: \$DOCKERCODE"

                echo "Grep Command Code: \$GREPCODE"

                if [ \\$DOCKERCODE -eq 0 ] then;
                    docker stop $APP_CONTAINER_NAME
                    docker rm $APP_CONTAINER_NAME
                else
                    echo "WARNING: Docker command was empty or had an error"
                fi
            '''

Output from above version:

TEST
+ docker ps -a
+ grep TEST
+ true
+ echo HERE
HERE
+ echo ${PIPESTATUS[@]}
${PIPESTATUS[@]}
+ DOCKERCODE=${PIPESTATUS[0]}
+ GREPCODE=${PIPESTATUS[1]}
+ echo Docker Command Code: ${PIPESTATUS[0]}
Docker Command Code: ${PIPESTATUS[0]}
+ echo Grep Command Code: ${PIPESTATUS[1]}
Grep Command Code: ${PIPESTATUS[1]}
/mnt/data/jenkins/workspace/Test@tmp/durable-4a5608fa/script.sh: 17: /mnt/data/jenkins/workspace/Test@tmp/durable-4a5608fa/script.sh: Syntax error: "else" unexpected (expecting "then")

FINAL ANSWER: The shebang needed to be on the same line as the script: ''' because of how just the first few characters are read by the system to check for #!.

sh label: 'Stop and Remove Old Docker Container', script: '''#!/usr/bin/env bash             
                docker ps -a
                echo $APP_CONTAINER_NAME

                docker ps -a | grep $APP_CONTAINER_NAME || true
                status=("${PIPESTATUS[@]}")
                DOCKERCODE=${status[0]}
                GREPCODE=${status[1]}
                echo "Docker Command Code: $DOCKERCODE"

                echo "Grep Command Code: $GREPCODE"

                if [ $DOCKERCODE -eq 0 ]; then
                    docker stop $APP_CONTAINER_NAME
                    docker rm $APP_CONTAINER_NAME
                else
                    echo "WARNING: Docker command was empty or had an error"
                fi
            '''
jdcskillet
  • 45
  • 7

1 Answers1

4

There seems to be some syntax issues and also I would suggest to use bash instead if using sh shell.

Try the below code and see if this works properly. (EDIT - Put shebang on first line to accept as answer)

sh label: 'Stop and Remove Old Docker Container', script: '''#!/usr/bin/env bash
                docker ps -a
                echo $APP_CONTAINER_NAME

                docker ps -a | grep $APP_CONTAINER_NAME || true
                status=("${PIPESTATUS[@]}")
                DOCKERCODE=${status[0]}
                GREPCODE=${status[1]}
                echo "Docker Command Code: $DOCKERCODE"

                echo "Grep Command Code: $GREPCODE"

                if [ $DOCKERCODE -eq 0 ]; then
                    docker stop $APP_CONTAINER_NAME
                    docker rm $APP_CONTAINER_NAME
                else
                    echo "WARNING: Docker command was empty or had an error"
                fi
            '''

In the above code, I have made changes in the way you were trying to get output of command docker ps -a | grep $APP_CONTAINER_NAME || true using PIPESTATUS variable. Since PIPESTATUS is a special variable, it's value gets updated after every command, so you were not getting any value of ${PIPESTATUS[1]}

The other change I have made is fixing the syntax issue in the line if [ $DOCKERCODE -eq 0 ] then; to if [ $DOCKERCODE -eq 0 ]; then

You can test out the code further.

jdcskillet
  • 45
  • 7
Samit
  • 1,021
  • 6
  • 11