2

For now I'm using this in my script:

set -euxo pipefail

This will make my bash script fail immediatly if there is an error in my pipe. When I leave this option my script will run fully and end with exit 0 (no error).

I want to have a mix of both. I want to end the whole script but have exit 1; at the end if there was an error in a pipe.

My script looks like this:

#!/bin/bash
set -euxo pipefail
curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call1' | jq -S "." > "output1.json"
curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call2' | jq -S "." > "output2.json"
cat output1.json
cat output2.json

So I don't want to exit the script if call1 fails. If call1 fails I want to go to call2 and the cat commands before exiting the script with exit code 1.

1
  • Closely related to this post on pipeline errors and how to deal with them. Please see that post for relevant answers also. Commented Nov 26, 2018 at 15:11

2 Answers 2

2

Don't use set -e as that will make script exit upon first error. Just save your exit codes after call1 and call2 and exit with appropriate exit code after cat commands:

#!/usr/bin/env bash -ux
set -uxo pipefail

curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call1' | jq -S "." > "output1.json"
ret1=$?
curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call2' | jq -S "." > "output2.json"
ret2=$?

cat output1.json
cat output2.json

exit $((ret1 | ret2))
Sign up to request clarification or add additional context in comments.

2 Comments

Without set -o pipefail if the first curl fails, the $? will be 0 anyway, because jq will/can succeed.
With curl --fail in place jq will fail if curl fails but we can surely add set -o pipefail
0

Subshells.

set -euo pipefail
export SHELLOPTS

(
   set -euo pipefail
   curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call1' | jq -S "." > "output1.json"
) && res1=$? || res1=$?

(
   set -euo pipefail
   curl --fail --compressed -u "$CREDS" -X GET --header 'Accept: xxx' --header 'Accept-Language: de-DE' 'https://api/call2' | jq -S "." > "output2.json"
) && res2=$? || res2=$?

if (( res1 != 0 || res2 != 0 )); then
   echo "Och! Command 1 failed or command 2 failed, what is the meaning of life?"
   exit 1;
fi

Subshell let's you grab the return value of the commands executed in it.

Comments

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.