Only the parent process (or the child subreaper if any or init
if the parent died), can retrieve the exit status of a process.
From the shell where you started the command, you can wait for it, and start b.sh
in background if a.sh
was successful with:
wait $pid && nohup b.sh &
In zsh or:
wait -f "$pid" && { nohup b.sh & }
In recent versions of bash (the -f
for wait
not to return when the process is only stopped; that's the default behaviour in zsh
).
However the wait
has to run in foreground. If run in background it would be in a child shell process and therefore would no longer be the parent of the process running nohup a.sh
.
To retrieve the exit status of a process that is not your child one approach is to use a debugger and intercept the _exit()
, exit_group()
or equivalent system calls.
For instance, on Linux, one could do:
ret=$(strace -qqqa0 -e signal=none -e exit_group -p "$pid" 2>&1 | grep -Po '\(\K\d+')
The macos equivalent would likely involve a truss
or dtrace
command, but I don't have a machine to test that on.
A && B
is not run B after A is finished, it's run B after A is finished and only if A was successful (exited with a 0 exit status). To run B after A, it's justA; B
or A and B on separate lines. – Stéphane Chazelas Nov 11 '23 at 07:21