Since such a command will run and (hopefully) complete in background, I cannot get its exit status; that is OK.
This statement is incorrect to begin with:
#!/bin/bash
some_command &
pid="$!"
wait -n "$pid"
echo "Status was ${?}."
If you want to be notified immediately, you can use a few signal-based tricks.
Handling of SIGCHLD
would be the most obvious option, but (1) its support in Bash is buggy and (2) despite set -b
, trap
handlers will actually wait for command boundaries.
That said, the next best option (which also interrupts long-runing foreground processing immediately when some_command
fails) is (an equivalent of) generating a Ctrl+C for your entire process group. This is delivered and acted upon immediately, the shell itself can handle the signal and continue, if desired, whereas the foreground process will, presumably, exit by default etc.
#!/bin/bash
set -e
handler() {
echo 'command failure signalled'
trap - INT
}
trap handler INT
background() {
local -ir pid="$1"
shift
"$@" || kill -INT -- -"$pid"
}
background "$$" some_command &
# long-running foreground task
echo 'before long processing'
sleep 5 || echo 'long processing interrupted'
echo 'after long processing'
Try to replace some_command
with (e.g.) sleep 2
to test the “successful” case.