Running in the background (via &)

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I have the following simple script.

#!/usr/bin/perl -w
print `resize`;

If I run it in the foreground it works just fine, but if I run it in the
background it hangs until I foreground it.  Is there  a way to tell if
you're running in the background - it may be a UNIX feature that you
cannot.  Otherwise, is there some way to diddle the environment (perhaps
redirecting file descriptors) so it won't hang?


Re: Running in the background (via &)

Mark Seger wrote:
Quoted text here. Click to load it

In a sense: you cannot as in *ix there is actually no conceptual
difference between a "foreground" and a "background" process.

The terms "foreground" and "background" are used to distinguish between
processes that the shell waits for and those that the shell doesn't wait
for (e.g. thos started with an ampersand). So it's the parent who
defines whether a process is a background process or a foreground
process and then, even that may change, e.g. if you start a process, do
quite a lot of different stuff (the new process could then be viewed as
running in the background), then wait for the process (it might then be
seen as a foreground process) until you are taken out of the wait() by a
signal, and continue (which would turn your process into a background
process again).
Also with some shells you can actively change processes between fore-
and background.

Quoted text here. Click to load it

Would it help to have an indication whether you're in the foreground or
in the background?
Usually background processes aren't connected to a terminal, most
important, STDIN won't be connected to a terminal as then two processes
(the current "foreground" process and the "background" process) contend
for the input from the keyboard, so you could check whether STDIN is a
This will fail if you have a foreground process that has stdin
redirected from a file or from a pipe, though.


These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize (T.  Pratchett)
Company Details:

Re: Running in the background (via &)

Quoted text here. Click to load it
that's what I thought and so did a -t STDIN, but it shows true whether
in the foreground or background.

Re: Running in the background (via &)

I have a solution, based on an example in the perl cookbook by calling
iloctl directly to get the terminal height and it seems to work in both
foreground and background. Can I count on the file being
present in asm?  Is there somewhere else I should look for it?

#!/usr/bin/perl -w
require "asm/";
my $winsize="" x 8;
if (ioctl(STDOUT, TIOCGWINSZ(), $winsize)) {
     ($rows)=(unpack('S4', $winsize))[0];
else  {
     print "ERROR\n";
print "rows: $rows\n";


Re: Running in the background (via &)

Quoted text here. Click to load it

This is wrong in general.

Quoted text here. Click to load it

That's why about 20 years ago, Unixes started to stop background
processes from reading from the terminal (see the SIGTTIN signal).

Quoted text here. Click to load it

Won't work.

Right. STDIN doesn't change. You can flip a process between foreground
and background (in most shells with the conveniently named commands "fg"
and "bg"), but it would be rather messy if that changed an open file
descriptor. What changes is whether the process group is the foreground
process group of the controlling terminal. The place to look for
POSIX (=UNIX) specific functionality is the POSIX module:

|      getpgrp This is identical to Perl’s builtin "getpgrp()" function for
|              returning the process group identifier of the current process,
|              see "getpgrp" in perlfunc.
|      tcgetpgrp
|              This is identical to the C function "tcgetpgrp()" for returning
|              the process group identifier of the foreground process group of
|              the controlling terminal.

If they are the same we should be in the foreground:

% perl -MPOSIX -le 'print getpgrp() == tcgetpgrp(STDIN) ? "foreground" :

% perl -MPOSIX -le 'print getpgrp() == tcgetpgrp(STDIN) ? "foreground" :
"background"' & sleep 1
[1] 23462
[1]  + done       perl -MPOSIX -le

Looks good.


Re: Running in the background (via &)

Quoted text here. Click to load it

And, POSIX misses if stdin/stdout are redirected:

perl -MPOSIX -le 'warn getpgrp()=3D=3Dtcgetpgrp(STDIN)
? foreground" : "background"' </dev/null >/dev/null
background at -e line 1.

Charles DeRykus

Site Timeline