The way I normally start a long-running shell script is
% (nohup ./script.sh </dev/null >script.log 2>&1 & )
The redirections close stdin
, and reopen stdout
and stderr
; the nohup
stops HUP reaching the process when the owning process exits (I realise that the 2>&1
is somewhat redundant, since the nohup
does something like this anyway); and the backgrounding within the subshell is the double-fork which means that the ./script.sh
process's parent has exited while it's still running, so it acquires the init process as its parent.
That doesn't completely work, however, because when I exit the shell from which I've invoked this (typically, of course, I'm doing this on a remote machine), it doesn't exit cleanly. I can do ^C
to exit, and this is OK – the process does carry on in the background as intended. However I can't work out what is/isn't happening to require the ^C
, and that's annoying me.
The actions above seem to tick most of the boxes in the unix FAQ (question 1.7), except that I'm not doing anything to detach this process from a controlling terminal, or to make it a session leader. The setsid(2) call exists on FreeBSD, but not the setsid
command; nor, as far as I can see, is there an obvious substitute for that command. The same is true on macOS, of course.
So, the questions are:
- Is there a differently-named caller of
setsid
on this platform, that I'm missing? - What, precisely, is happening when I exit the calling shell, that I'm killing with the
^C
? Is there any way this could bite me?
Related questions (eg 1, 2) either answer a slightly different question, or assume the presence of the setsid
command.
(This question has annoyed me for years, but because what I do here doesn't actually not work, I've never before got around to investigating, getting stumped, and asking about it).