3

I have a script (run-docker-container.sh) that calls another script (create-docker-container.sh). create-docker-container executes a curl script against the docker remote api and returns the http code or zero if successful. The create script returns thus-wise

echo $RVAL
exit $RVAL

and in my tests has the value for $RVAL as 404, the value I'm interested in for this question.

In my run-docker-container script, I have the following lines

create-docker-container.sh $CONTAINER_NAME $CONTAINER_SETTINGS
rval=$?
echo $rval
if [ $rval -eq 404 ]; then
    ...
fi

even though create appears to be exiting with 404, the value I'm getting for $? is 148 and thus my condition handling is not being called. Why would this be and how do I properly get the exit code from the script?

  • 3
    404-256=148.... 8-bit arithmetic rules :) return codes are 8-bit values – MelBurslan Mar 17 '16 at 16:25
  • ah! I did not know that. Thats...why? I would think it would be register size... – Kevin Milner Mar 17 '16 at 16:32
  • as an alternative, your create-docker-container.sh script can echo the return value of 404 as the last thing before exiting and your script can capture that one from STDIN instead of the exit code. This is how I would do it, after checking a successful exit code (i.e. 0) – MelBurslan Mar 17 '16 at 16:36
  • 1
    @KevinMilner the eight bits are a subset of the 16-bit status word returned by wait(2), so have nothing to do with register size. See e.g. lib/prexit.c from apuebook.com/src.3e.tar.gz to experiment with return values from processes that exit normally, are signaled, or core dump. – thrig Mar 17 '16 at 16:47
  • 2
    Well, it has to do with register size on the PDP-11. Unix system calls generally returned values in one or two 16-bit registers, and set the C bit on error. Aside from filling buffers (like stat did), that's the way they communicated results back to the user. wait had its hands full returning a 16-bit pid and a 16-bit status word containing a signal and exit value. Then things got standardized, so we're kind of stuck with 8-bit values. – Mark Plotnick Mar 17 '16 at 17:12
4

For historical reasons, the exit status of a process is an 8-bit number. The number that you pass to exit is reduced modulo 256 (2⁸).

Furthermore values 126 and above have a conventional meaning, indicating a failure to start the program (126 or 127) or a program that was killed by a signal (128 and above). So while you can return such values, you shouldn't unless you want to simulate these conditions.

The rule is to return 0 for success and some other value to indicate errors. This is a rule inasmuch as many tools interpret 0 as success: conditional commands such as if and while, tools that abort on errors such as shell scripts under set -e and makefiles, etc.

Regarding errors, the most common conventions are to return 1 on any error, or to return 2 on any error. The thirdmost common convention is to return 1 on an expected failure (e.g. a search command that finds nothing) and 2 on an unexpected failure (e.g. the file to search in did not exist). If you need to map HTTP error codes into exit status, you have the range 1–125 to play in (with 200 success mapping to 0), there's no standard for that.

  • Wasn't aware of the "thirdmost common convention" but it makes perfect sense; thank you! – Wildcard Mar 18 '16 at 1:39

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.