0

I have below script which I will be running via jenkins:

#!/bin/bash

function getToken
{ 
    echo "function to get token"
}

function call_init
{
    echo "Creating a config file"

}

function call_list
{
    echo "calling list*"
}

#Starting execution
if [[ -z "$TOKEN" ]]; then
    TOKEN=$(getToken)
    if [ $? -ne 0 ]; then
    exit 1
    fi
fi

echo "Creating a config file and populating it"
call_init
if [ $? -ne 0 ]; then
exit 1
fi


if [ -n $ACTION ]; then
case "$ACTION" in

'list')  echo "Action is list"
     call_list
     if [ $? -ne 0 ]; then
     exit 1
     fi   
;;
'update')  echo  "Section is update"
;;
'delete')  echo  "Section is delete"
;;
*) echo "This is a default message"
   ;;
esac
fi

As you see that theres a lot of repetition of the below code which helps me fail the jenkins job by throwing the error code 1:

if [ $? -ne 0 ]; then
exit 1
fi

What would be the most efficient way to handle this? I need it to always exit the code with 1.

P.S: I went through Checking Bash exit status of several commands efficiently, however was not able to get it work for the above script.

3
  • well. is it a mandate? Somehow, my functions are getting executed. Commented May 14, 2018 at 12:55
  • 2
    Just use the construction call_list || exit 1. Commented May 14, 2018 at 13:06
  • 1
    Note that the reason you weren't able to get the solution you cite working is primarily that the accepted answer on that question is less than ideal. (I'm trying to be diplomatic. It is a terrible solution.) Commented May 14, 2018 at 13:08

1 Answer 1

3

The best approach is to use explicit error checking.

Your current pattern can be streamlined, the following are all equivelant:

run_command
if [ $? -ne 0 ]; then
    print_error
    exit 1
fi
if ! run_command; then
    print_error
    exit 1
fi
run_command || { print_error; exit 1; }

Or in its simplest form, with no error message:

run_command || exit 1

As an alternative, you might want to use set -e. You might also be interested in set -o pipefail.

These are not the preferred solution, as @William has pointed out, but can be useful for getting simple scripts to throw errors:

Note that set -e is generally not considered best practice. It's semantics are extremely unexpected in the edge cases (eg, if you invoke set -e in a function), and more importantly have changed dramatically with different versions of the shell. It is far better to explicitly invoke exit by running cmd || exit

You can use set -e to cause bash to bail out if a command returns non-zero, and set +e to disable this behaviour.

set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
    Set or unset values of shell options and positional parameters.

    Change the value of shell attributes and positional parameters, or
    display the names and values of shell variables.

    Options:
      [...]
      -e  Exit immediately if a command exits with a non-zero status.
      [...]
      -o option-name
          Set the variable corresponding to option-name:
              [...]
              pipefail     the return value of a pipeline is the status of
                           the last command to exit with a non-zero status,
                           or zero if no command exited with a non-zero status
              [...]

To make use of this, you must enable the option before it would be required.

For example:

# disable 'exit immediately' (the default)
set +e

echo "running false..."
false
echo "we're still running"

# enable 'exit immediately'
set -e

echo "running false..."
false
echo "this should never get printed"

set -o pipefail must be used in conjunction with set -e:

# enable 'exit immediately'
set -e

# disable 'pipefail' (the default)
set +o pipefail

echo "running false | true..."
false | true
echo "we're still running (only the last exit status is considered)"

# enable 'pipefail'
set -o pipefail

echo "running false | true..."
false | true
echo "this should never get printed"
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you..how can this be used in my script? I had tried set -e, but nothing happened
I've added a note on its usage.
Note that set -e is generally not considered best practice. It's semantics are extremely unexpected in the edge cases (eg, if you invoke set -e in a function), and more importantly have changed dramatically with different versions of the shell. It is far better to explicitly invoke exit by running cmd || exit
Hah, I was just adding a note about that... Perhaps I'll make set -e a note to explicit error checking...
@WilliamPursell Updated

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.