2

I'm running a program where an exit code of either 0 or 1 indicates success. I'm running this while building a docker image, so if the return code is not 0, the build fails. How can I capture the exit code and force an exit code of 0 if the actual exit code is 0 or 1 so that the docker image can properly build?

I've tried something like this where (exit 1) represents the program:

((exit 1) && if [ $? == 0 || $? == 1]; then exit 0; else exit 1; fi;)

but it's not working, an exit code of 1 still exits with 1.

I would rather not do program || true in case the program actually does fail for some reason

Thanks!

Matt
  • 35
  • 7

2 Answers2

2

The problem here is that exit 0 has a truthy value, while exit 1 has a falsy value. This means that the right-part of your condition is only executed when the first part is true (because of the && operator).

If your program exits with code 0, you don't have anything to do. However, what you do want is "transform" a code 1 to a code 0. And to do so, the || operator is what you need.

This should work:

((exit 1) || if [ $? = 1 ]; then exit 0; else exit 1; fi)

A few tests to check (I changed the exit code values to better understand what's happening):

$> ((exit 0) || if [ $? = 1 ]; then exit 2; else exit 3; fi); echo $?
0  # the right-part of the condition is ignored
$> ((exit 1) || if [ $? = 1 ]; then exit 2; else exit 3; fi); echo $?
2  # the exit code 1 is "converted" into an exit code 2 (or 0 in your case)
$> ((exit 2) || if [ $? = 1 ]; then exit 2; else exit 3; fi); echo $?
3  # the exit code 2 is "converted" into an exit code 3 (or 1 in your case)
julienc
  • 19,087
  • 17
  • 82
  • 82
1

I ran into another problem when implementing this in my dockerfile that I'll note here along with the solution I used just in case anyone else has a similar issue and comes across this.

When I run this:

RUN (update_blastdb.pl --decompress taxdb || if [ $? == 1 ]; then exit 0; else exit 1; fi;)

I get an error message:

Downloading taxdb.tar.gz... [OK]
Decompressing taxdb.tar.gz ... [OK]
/bin/sh: 1: [: 1: unexpected operator
The command '/bin/sh -c (update_blastdb.pl --decompress taxdb || if [ $? == 1 ]; then exit 0; else exit 1; fi;)' returned a non-zero code: 1

Apparently docker doesn't run the RUN commands using bash by default and you have to add SHELL ["/bin/bash", "-c"] beforehand so that this code can run properly. Then it works.

Matt
  • 35
  • 7
  • 1
    This is because "==" is bash specific, but you can simply use "=" instead to be posix-compatible (see https://stackoverflow.com/a/20449556/2679935) – julienc Mar 30 '20 at 15:29
  • There always seems to be so many details that I just don't know... x-0 Thanks! – Matt Mar 30 '20 at 15:34
  • I didn't know about it either, but I had to look for it to know why you got this message :) On my Linux distribution, `sh` is actually a symbolic link to `bash`, so I never had to care about this before! – julienc Mar 30 '20 at 15:36