I have a bash script start.sh which looks like this:
for thing in foo bar; do
{
background_processor $thing
cleanup_on_exit $thing
} &
done
This does what I want: I run start.sh, it exits with code 0, and the two subshells run in the background. Each subshell runs background_processor
, and when that exits, it runs cleanup_on_exit
. This works even if I exit the terminal from which I originally ran start.sh (even if that was an ssh connection).
Then I tried this:
ssh user@host "start.sh"
This works, except that after start.sh
has exited, ssh apparently also waits for the subshells to exit. I don't really understand why. Once start.sh
exits, the subshells become children of pid 1, and they are not even assigned with a tty... so I can't understand how they are still associated with my ssh connection.
I later tried this:
ssh -t user@host "start.sh"
Now the processes have an assigned pseudo-tty. Now, I find that ssh does exit as soon as start.sh
exits, but it also kills the child processes.
I guessed that the child processes were being sent SIGHUP in the latter case, so I did this:
ssh -t user@host "nohup start.sh"
That actually works! So, I have a solution to my practical problem, but I would like to grasp the subtleties of the SIGHUP/tty stuff here.
In summary, my questions are:
- Why does ssh (without -t) wait for the child processes even after
start.sh
exits, even though they have parent pid 1? - Why does ssh (with -t) kill the child processes, apparently with a SIGHUP, even though that does not happen when I run them from a terminal and log out of that terminal?