Discussion:
nohup Versus setsid
(too old to reply)
Lawrence D'Oliveiro
2024-09-12 04:23:42 UTC
Permalink
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1). Compare the docs for
yourself <https://manpages.debian.org/1/nohup.1.en.html> vs
<https://manpages.debian.org/1/setsid.1.en.html>, and tell me why we
still need nohup when we have setsid?
Kenny McCormack
2024-09-12 11:37:58 UTC
Permalink
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1). Compare the docs for
yourself <https://manpages.debian.org/1/nohup.1.en.html> vs
<https://manpages.debian.org/1/setsid.1.en.html>, and tell me why we
still need nohup when we have setsid?
First, I do get what you're saying - and I've both A) Used setsid(2) a lot
over the years so am familiar with it and B) Always thought that nohup(1)
was old and crusty. I cringe whenever I hear people recommend it in help
groups nowadays.

That said, it is kind of apples-to-oranges comparison. nohup(1) is more of
a command, while setsid(1) is really just a thin wrapper around the system
call. According to the man page, nohup(1) does a lot of things, including
setting up logging and so on; there is no underlying system call. OTOH, to
understand setsid(1), you really have to understand the underlying system
call - and that system call is not simple. It (setsid(2)) is kind of a
"bigger/better" version of setpgrp() and it has some interesting
restrictions on its use. In a way, it could be said that both sessions and
process groups were only implemented to support shell job control, and this
is kind of a funny thing, since shell job control is now sort of thought of
as an anachronism (I still use it, but I seem to be in some kind of minority).

So, despite what I said 2 paragraphs ago, nohup(1) may be better as a
recommendation to the newbie.

Just out of curiosity, what is the underlying-context/reason-for-posting of
this thread? And, why in a shell group? Isn't it really a
comp.unix.programmer type question?
--
Just for a change of pace, this sig is *not* an obscure reference to
comp.lang.c...
Janis Papanagnou
2024-09-12 12:01:37 UTC
Permalink
Post by Kenny McCormack
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1). Compare the docs for
yourself [...], and tell me why we still need nohup when we have setsid?
I don't know the details, but the descriptions look quite different...
nohup - run a command immune to hangups, with output to a non-tty
setsid - run a program in a new session
Post by Kenny McCormack
First, I do get what you're saying - and I've both A) Used setsid(2) a lot
over the years so am familiar with it and B) Always thought that nohup(1)
was old and crusty. I cringe whenever I hear people recommend it in help
groups nowadays.
Yes it's old; existing almost from Unix' beginning (at least Version 7).
But I used nohup a couple times, to have the function described above.
(I've never used setsid, never needed it, didn't even know it exists.)
Post by Kenny McCormack
That said, it is kind of apples-to-oranges comparison. nohup(1) is more of
a command, while setsid(1) is really just a thin wrapper around the system
call. According to the man page, nohup(1) does a lot of things, including
setting up logging and so on; there is no underlying system call. OTOH, to
understand setsid(1), you really have to understand the underlying system
call - and that system call is not simple. It (setsid(2)) is kind of a
"bigger/better" version of setpgrp() and it has some interesting
restrictions on its use. In a way, it could be said that both sessions and
process groups were only implemented to support shell job control, and this
is kind of a funny thing, since shell job control is now sort of thought of
as an anachronism (I still use it, but I seem to be in some kind of minority).
Well, count me to the minority.

But why are you saying that "job control is now sort of thought of as
an anachronism"?
Post by Kenny McCormack
So, despite what I said 2 paragraphs ago, nohup(1) may be better as a
recommendation to the newbie.
A non-technical but more fundamental answer can be that nohup is POSIX
standard while the other is not (with all consequences for the general
case, portability, etc.).

Janis
Lawrence D'Oliveiro
2024-09-12 22:02:10 UTC
Permalink
Post by Janis Papanagnou
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1).
I don't know the details, but the descriptions look quite different...
nohup - run a command immune to hangups, with output to a non-tty
setsid - run a program in a new session
The effect is supposed to be the same: spawn a background task that will
continue running after you log out.
vallor
2024-09-12 23:07:07 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Janis Papanagnou
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1).
I don't know the details, but the descriptions look quite different...
nohup - run a command immune to hangups, with output to a non-tty
setsid - run a program in a new session
The effect is supposed to be the same: spawn a background task that will
continue running after you log out.
That's not the only thing that the (POSIX) nohup(1) tool does.

I prefer the simplicity of nohup's behavior, and use it when doing
"big" compiles.

I have a script:
$ cat go.sh
time -p make -j64

So I can:
$ nohup ./go.sh &

Then I can watch for status without flooding the terminal:

$ while : ; do tail nohup.out ; date; sleep 5 ; done

Everybody has their own way of doing things, but this works
on any POSIX system, not just Linux[*].

[*] Though, truth be told, I'm mostly using it to
compile Linux.
--
-Scott System76 Thelio Mega v1.1 x86_64 NVIDIA RTX 3090 Ti
OS: Linux 6.11.0-rc7 Release: Mint 21.3 Mem: 258G
"E Pluribus UNIX."
Lawrence D'Oliveiro
2024-09-12 23:13:19 UTC
Permalink
Post by vallor
Post by Lawrence D'Oliveiro
The effect is supposed to be the same: spawn a background task that
will continue running after you log out.
That's not the only thing that the (POSIX) nohup(1) tool does.
But then, you cannot do more than one nohup invocation at a time, if one
is already writing to nohup.out.

With setsid, I just specify an output log file for each invocation, and I
can tail that in the usual way, same as you do.
Janis Papanagnou
2024-09-13 01:44:18 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by vallor
Post by Lawrence D'Oliveiro
The effect is supposed to be the same: spawn a background task that
will continue running after you log out.
That's not the only thing that the (POSIX) nohup(1) tool does.
But then, you cannot do more than one nohup invocation at a time, if one
is already writing to nohup.out.
If it's only the output file that is an issue I seem to recall that
there's a way to write to a different file (unless it's appended to
nohup). A long time passed that I used nohup - I thought there was
an option to define the output file - but if I inspect the specs it
seems that redirection of stdin suffices to choose arbitrary files.

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/nohup.html

(Did I misread the POSIX specs?)
Post by Lawrence D'Oliveiro
With setsid, I just specify an output log file for each invocation, and I
can tail that in the usual way, same as you do.
Janis
Helmut Waitzmann
2024-09-13 16:35:00 UTC
Permalink
A long time passed that I used nohup - I thought there was an
option to define the output file - but if I inspect the specs it
seems that redirection of stdin suffices to choose arbitrary
files.
If you substitute stdout for stdin you'll get what the standard
describes in
(<https://pubs.opengroup.org/onlinepubs/9799919799/utilities/nohup.html#tag_20_89_03>):


If standard error is a terminal and standard output is open but
is not a terminal, all output written by the named utility to its
standard error shall be redirected to the same open file
description as the standard output.


nohup a_command ... >> an_arbitrary_file
(Did I misread the POSIX specs?)
Other than that you read "stdin" where the POSIX specs write
"stdout", no.
Janis Papanagnou
2024-09-13 16:53:12 UTC
Permalink
Post by Janis Papanagnou
(Did I misread the POSIX specs?)
Other than that you read "stdin" where the POSIX specs write "stdout", no.
Oh, thanks! (That was actually a typo.)

Janis
Kaz Kylheku
2024-09-13 00:37:54 UTC
Permalink
Post by vallor
Post by Lawrence D'Oliveiro
Post by Janis Papanagnou
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1).
I don't know the details, but the descriptions look quite different...
nohup - run a command immune to hangups, with output to a non-tty
setsid - run a program in a new session
The effect is supposed to be the same: spawn a background task that will
continue running after you log out.
That's not the only thing that the (POSIX) nohup(1) tool does.
I prefer the simplicity of nohup's behavior, and use it when doing
"big" compiles.
$ cat go.sh
time -p make -j64
$ nohup ./go.sh &
$ while : ; do tail nohup.out ; date; sleep 5 ; done
Everybody has their own way of doing things, but this works
on any POSIX system, not just Linux[*].
I have this:

$ time -p make -j64 | pw &

Where pw is PipeWatch: https://www.kylheku.com/cgit/pw/about/

pw continuously reads its input, and refreshes the terminal
with samples of the input.

When pw is put into the job control background, it knows this,
and avoids writing to the terminal, while continuing to read
standard input, and performing its activities like capturing
triggered snapshots.

When you foreground it, the display refreshes.

pw is not a pager; it does not buffer everything and does not
let you scroll through the history. It captures terminal-window-sized
snapshots consisting of lines.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Kaz Kylheku
2024-09-12 12:11:35 UTC
Permalink
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of doing
what can be done more elegantly using setsid(1). Compare the docs for
yourself <https://manpages.debian.org/1/nohup.1.en.html> vs
<https://manpages.debian.org/1/setsid.1.en.html>, and tell me why we
still need nohup when we have setsid?
Did you notice that this is comp.unix.shell, not comp.linux.shell?

You might use nohup when you're on a system that isn't Linux.

nohup is described in POSIX (and on GNU/Linux systems, it comes from
GNU Coreutils) whereas setsid (the command) is something from util-linux.

$ setsid
-bash: setsid: command not found
$ uname -a
Darwin m1box.example.net 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug
22 20:20:05 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T8101 arm64
$ nohup
usage: nohup [--] utility [arguments]
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Helmut Waitzmann
2024-09-13 17:00:45 UTC
Permalink
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of
doing what can be done more elegantly using setsid(1). Compare
the docs for yourself
<https://manpages.debian.org/1/nohup.1.en.html> vs
<https://manpages.debian.org/1/setsid.1.en.html>, and tell me
why we still need nohup when we have setsid?
Because there is a real difference between both of them.


"nohup" makes the invoked command immune to the HUP signal but
lets it remain in its terminal session, i. e. the command to be
run will not lose its controlling terminal.  Thus the other job
control signals like TSTP, INT, and QUIT sent by the terminal
driver to the command may have their effects.


Also, the HUP signal will be ignored regardless of its origin
(terminal driver as well as the "kill(2)" system call).


If, on the other hand, you use "setsid", the command to be run
will not be made immune to any of the job control signals,
i. e. any job control signal sent to the command to be run by
means of the kill(2) system call will have its effect.


Also, as the command to be run will leave the terminal session
and thus lose the controlling terminal of the invoker, it won't
be affected by any job control signal sent by the terminal driver
of the invoker's controlling terminal, for example when typing
the interrupt, suspend or quit key on the keyboard no signal will
reach the command to be invoked.
Kaz Kylheku
2024-09-13 17:26:37 UTC
Permalink
Post by Helmut Waitzmann
Post by Lawrence D'Oliveiro
It has long seemed to me that nohup(1) was an old, hacky way of
doing what can be done more elegantly using setsid(1). Compare
the docs for yourself
<https://manpages.debian.org/1/nohup.1.en.html> vs
<https://manpages.debian.org/1/setsid.1.en.html>, and tell me
why we still need nohup when we have setsid?
Because there is a real difference between both of them.
Don't confuse low drop-out with too many facts.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Lawrence D'Oliveiro
2024-09-13 22:32:58 UTC
Permalink
"nohup" makes the invoked command immune to the HUP signal but lets it
remain in its terminal session, i. e. the command to be run will not
lose its controlling terminal.  Thus the other job control signals like
TSTP, INT, and QUIT sent by the terminal driver to the command may have
their effects.
See, I always thought the point of that was to allow the job to continue
after you log off. After all, what was the original meaning of the “HUP”
(hangup) signal? It meant the modem had disconnected -- the phone line had
hung up.
If, on the other hand, you use "setsid", the command to be run will not
be made immune to any of the job control signals, i. e. any job control
signal sent to the command to be run by means of the kill(2) system
call will have its effect.
That’s because setsid starts an entirely new session group, not connected
to your terminal at all. So it is not vulnerable to any of those remaining
signals from your terminal, that nohup does not block.

That’s another reason why I think setsid is better than nohup.

Loading...