Why does the following print 0? I expected it to print 1234.
$ bash -c exit 1234
$ echo $?
bash -c exit 1234
runs bash with the separate arguments -c, exit, and 1234. -c consumes the argument immediately following it, so bash runs exit only; 1234 is used as the first positional parameter ($0, the name of the shell).
To get bash to exit with a given code, you need to quote the whole command:
bash -c "exit 1234"
Note that bash exit statuses are limited to 0-255, so this produces an exit status of 210 (1234 % 256).
You can't with bash's exit builtin even if you fix your code to run exit 1234 instead of exit alone, as bash takes upon itself to truncate the value to 8 bits:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
You need to execute another command in the same process that can exit with arbitrary values:
$ strace -e exit_group bash -c 'exec perl -e "exit 1234"'
exit_group(1234) = ?
$ strace -e exit_group bash -c 'exec zsh -c "exit 1234"'
exit_group(1234) = ?
In any case, note that some systems like Linux don't let the parent process access the full value of that exit status even when using the waitid() API or a SIGCHLD sigaction() handler which is required by POSIX not to truncate it.
More details on that at: