bin/124748: [patch] sh(1): sh -c 'exit -1' fails with "Illegal number: -1", instead of exiting with a code of 255

Jilles Tjoelker jilles at
Sun May 24 19:20:05 UTC 2009

The following reply was made to PR bin/124748; it has been noted by GNATS.

From: Jilles Tjoelker <jilles at>
To: Garrett Cooper <gcooper at>
Cc: bug-followup at
Subject: Re: bin/124748: [patch] sh(1): sh -c 'exit -1' fails with "Illegal
	number: -1", instead of exiting with a code of 255
Date: Sun, 24 May 2009 21:14:57 +0200

 On Sun, Apr 26, 2009 at 06:46:43PM -0700, Garrett Cooper wrote:
 > On Sun, Apr 26, 2009 at 7:40 AM, Jilles Tjoelker <jilles at> wrote:
 > > Do people actually use 'exit -1' instead of the clearer 'exit 255'? '-1'
 > > is not an unsigned integer, so not a posix compliant parameter to the
 > > exit special builtin. Even then, sh still aborts a script with a nonzero
 > > exit code if exit is used wrongly like this.
 > Some people do, but I've since then stopped doing this.
 > The question I have is:
 > - Is the value of the return code uint8_t?
 On the kernel level it is, see wait4(2) and exit(3).
 On the shell level this is not necessarily the case.
 FreeBSD's /bin/sh allows more bits to be 'return'ed from functions and
 to appear in $?; it seems unwise to take advantage of this.
 ksh93 uses 256+sig instead of 128+sig for commands terminated by
 signals, which makes it possible for the shell to replicate command exit
 status more precisely. For example:
   ksh93 -c 'sh -c "kill -9 \$\$"; exit'
 exits on signal 9, not with status 137. This does not work entirely
 correctly -- for example, replacing exit with exit $? makes it
 exit with status 9 -- but I think it can be done properly. On the other
 hand this may not be so nice with logged signals (SIGSEGV etc).
 > - Where in the documentation for sh(1) does it say that it can't be
 > <0? Here are all of the relevant documentation items for exit codes I
 > could find:
 >    Command Exit Status
 >      Each command has an exit status that can influence the behavior of other
 >      shell commands.  The paradigm is that a command exits with zero for nor-
 >      mal or success, and non-zero for failure, error, or a false indication.
 >      The man page for each command should indicate the various exit codes and
 >      what they mean.  Additionally, the built-in commands return exit codes,
 >      as does an executed shell function.
 >      If a command is terminated by a signal, its exit status is 128 plus the
 >      signal number.  Signal numbers are defined in the header file
 >      <sys/signal.h>.
 > ----
 >      exit [exitstatus]
 >              Terminate the shell process.  If exitstatus is given it is used
 >              as the exit status of the shell; otherwise the exit status of the
 >              preceding command is used.
 > ----
 > Nowhere in the above documentation does it mention valid limits being
 > in the set, [0, 128+SIGRTMAX] => [0, 254]. It's merely implied by the
 > resources at one's disposal (the source, sys/signal.h, etc).
 I suppose that could be added (0..255).
 Jilles Tjoelker

More information about the freebsd-bugs mailing list