1

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
            '''
4
  • Are you not getting correct value of ${PIPESTATUS[0]} in the DOCKERCODE variable ? – Samit Nov 26 '19 at 19:20
  • Also, can you let me know what is the exact error you are getting while running the job? – Samit Nov 26 '19 at 19:25
  • It doesn't get to the PipeStatus step at all. + docker ps -a + grep TEST + true + echo HERE HERE /mnt/data/jenkins/workspace/Test@tmp/durable-4c7b4748/script.sh: 7: /mnt/data/jenkins/workspace/Test@tmp/durable-4c7b4748/script.sh: Bad substitution – jdcskillet Nov 26 '19 at 19:40
  • Note - I did put the output of the docker ps -a command... that works as expected. – jdcskillet Nov 26 '19 at 19:47
2

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.

2
  • Error I received below. I am going to putz with trying to get the command to not try and interpolate the pipestatus. Thanks for those other fixes. /mnt/data/jenkins/workspace/Test@tmp/durable-f7d43538/script.sh: 7: /mnt/data/jenkins/workspace/Test@tmp/durable-f7d43538/script.sh: Syntax error: "(" unexpected – jdcskillet Nov 26 '19 at 21:54
  • I got it. If you, @Samit, update your answer I'll choose it as the accepted one. Turns out, the system only reads the first few characters looking for the shebang. Therefore, the answer is above, but with the #!/usr/bin/env bash on the same line as the triple ticks ('''). – jdcskillet Dec 12 '19 at 22:26

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.