Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ksh, nohup, and background processes

822 views
Skip to first unread message

JR Tietsort

unread,
Jun 4, 1998, 3:00:00 AM6/4/98
to

I'm trying to write a little script so that I can learn how backgrounding
stuff really works (&, bg, fg, jobs, ^Z). I've written this script to test
with:


---- code ----
#!/usr/bin/ksh

until false
do
echo "running"
sleep 10
done
---- code ----

For the most part, this works as expected, but when I issue the command:
`nohup loop.ksh &`, it goes to the back as it should, but as soon as I go to
run another command at my prompt, it gives me this message:

[1] + Stopped(SIGTTOU) nohup loop.ksh &

I can't seem to find much information on why this is stopping, but when I do
something similar in PERL, then it works as expected and stays running. I
also couldn't get a good understanding of the SIGTTOU signal. I'm still
kind of new to this stuff....

Thanks for any leads....
J.R. Tietsort

brian hiles

unread,
Jun 5, 1998, 3:00:00 AM6/5/98
to

JR Tietsort (jrtie...@micron.com) wrote:
: I'm trying to write a little script so that I can learn how backgrounding

: stuff really works (&, bg, fg, jobs, ^Z). I've written this script to test
: with:
: ---- code ----
: #!/usr/bin/ksh
: until false
: do
: echo "running"
: sleep 10
: done
: --
: For the most part, this works as expected, but when I issue the command:

: `nohup loop.ksh &`, it goes to the back as it should, but as soon as I go to
: run another command at my prompt, it gives me this message:
: [1] + Stopped(SIGTTOU) nohup loop.ksh &
: I can't seem to find much information on why this is stopping, but when I do
: something similar in PERL, then it works as expected and stays running. I
: also couldn't get a good understanding of the SIGTTOU signal. I'm still
: kind of new to this stuff....
: Thanks for any leads....
: J.R. Tietsort

Gee, it's all documented in the man pages for ksh [keyword: "Job
Control"]. The only other thing you will need to know it that
SIGTTOU is a signal send to backgrounded process when attempting
to output to a terminal, and if not caught by a signal handler in
the code, will cause the process in question to stop (the same
thing that happens when you type control-Z.)

Bg and fg are basically commands that send the signals SIGTSTP and
SIGCONT respectively to the job in question.

man stty [keyword: tostop]

-Brian

Keith Ewen

unread,
Jun 5, 1998, 3:00:00 AM6/5/98
to

brian hiles wrote in message <6l7dn9$pek$3...@supernews.com>...

>-Brian

But I thought that by using 'nohup' all output would be sent to nohup.out,
so
why does this process send a signal, as the echo command would send its
output to nohup.out ?

Keith

brian hiles

unread,
Jun 9, 1998, 3:00:00 AM6/9/98
to

Keith Ewen (keith...@MCI2000.com) wrote:
: brian hiles wrote in message <6l7dn9$pek$3...@supernews.com>...
: >JR Tietsort (jrtie...@micron.com) wrote:
: : ...
: >Gee, it's all documented in the man pages for ksh [keyword: "Job

: >Control"]. The only other thing you will need to know it that
: >SIGTTOU is a signal send to backgrounded process when attempting
: >to output to a terminal, and if not caught by a signal handler in
: >the code, will cause the process in question to stop (the same
: >thing that happens when you type control-Z.)
: >-Brian

: But I thought that by using 'nohup' all output would be sent to
: nohup.out, so why does this process send a signal, as the echo
: command would send its output to nohup.out ?
: Keith

First of all, I meant that stop and bg and equivalent to ^Z (kill -SIGTSTP)
and kill -SIGCONT respectively.

Also, it is not true that this "process sends a signal," since
it is the job of the kernel to send the SIGTTOU signal to the process that
attempts to write to the terminal.

An addenda: "nohup" in ksh88 is actually a builtin that executes
the process/job (whether the shell option monitor option is set to
"on" or not) ignoring the SIGHUP signal.

Other than this, Keith's question is an entirely good one, and in
investigating the _documented_ reasons, I find the problem to be
subtler than had initially appeared.

The relevant section describing the low-level implementation of
job-control through its shell's implementation using the kernel
resources is from termios(3) man page below:

If a process is in the foreground process group of its controlling termi-
nal, write operations are allowed. Attempts by a process in a background
process group to write to its controlling terminal will cause the process
group to be sent a SIGTTOU signal unless one of the following special
cases apply: If TOSTOP is not set, or if TOSTOP is set and the process
is ignoring or blocking the SIGTTOU signal, the process is allowed to
write to the terminal and the SIGTTOU signal is not sent. If TOSTOP is
set, and the process group of the writing process is orphaned, and the
writing process is not ignoring or blocking SIGTTOU, the write returns -1
with errno set to EIO and no signal is sent.

All processes spawned from that login shell are in the same session,
and inherit the controlling terminal. One's shell normally groups
related processes together by placing them into the same process
group, the set of processes in the same process group collectively
referred to as a "job". The foreground process group of the terminal
is in the "foreground" when the same as the process group of a
particular job. Whereas when different, the process group of a job
(but still the controlling terminal,) that job is said to be in
the "background".

The controlling terminal is inherited by a child process during a
fork(2) system call. A process relinquishes its controlling terminal
_only_ when it creates a new session with the function. A process
does not relinquish its controlling terminal simply by closing all
of its file descriptors associated with the controlling terminal
if other processes (such as the shell) continue to have it open.

So, the controlling terminal (which, speaking informally, is unique
for any process group, which is the operative concept here...) is
_still_ the output device, not the file "nohup.out," upon invocation,
until the process itself will redirect its own output, when it
recognizes the above.

The man page for nohup(1) states:

The nohup utility invokes command with its arguments and at this time
sets the signal SIGHUP to be ignored. The signal SIGQUIT may also be set
to be ignored. If the standard output is a terminal, the standard output
is appended to the file nohup.out in the current directory. If standard
error is a terminal, it is directed to the same place as the standard
output.

So, the controlling terminal (which, speaking informally, is unique
for any process group, which is the operative concept here...) is
_still_ the output device, not the file "nohup.out," upon invocation,
until the process itself will redirect its own output, when it
recognizes the above.

This is why "nohup echo foo &" will raise SIGTSTP, whereas "nohup
echo foo >nohup.out &" will not, even though the redirected output
is to the same place!

Apparently because perl is its own "shell," in the regard to the fact the
it manipulates its own processes, it detaches the background process from
the controlling terminal and so does not invoke SIGTSTP from the kernel--
but this is conjecture.

Well, I hope to have confused you _much_ more than you were, having
been living in ignorant bliss! :)

-Brian

0 new messages