Mark Dominus on 7 Jan 2004 22:38:46 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: process in the background


------- Forwarded Message

Forwarded: Wed, 07 Jan 2004 17:26:07 -0500
Return-Path: mjd@plover.com
Delivery-Date: Wed Jan 07 22:23:00 2004
Return-Path: <mjd@plover.com>
Delivered-To: mjd-filter-none@plover.com
Received: (qmail 23819 invoked by uid 119); 7 Jan 2004 22:23:00 -0000
Message-ID: <20040107222300.23818.qmail@plover.com>
To: Jeff Abrahamson <jeff@purple.com>
Subject: Re: process in the background 
In-reply-to: Your message of "Wed, 07 Jan 2004 15:07:25 EST."
             <20040107200725.GB11631@purple.com> 
Date: Wed, 07 Jan 2004 17:23:00 -0500
From: Mark Jason Dominus <mjd@plover.com>


> According to perlipc, this should work:
> 
>     perl -e '$x=`(sleep 2;hostname)&`;print $x;'

I see nothing in perlipc that resembles that.  And I find it hard to
believe that it *would* say that, because it's apparent to me that it
won't do what you want.

> Maybe perl is waiting on its children before terminating or cares that
> I am looking at the command's stdout. 

It does.  `...` means to read from the command's stdout.  Perl has an
open descriptor, attached to the reading end of a pipe; the shell's
stdout is attached to the writing end.  Because you used backticks,
you told perl to wait for the complete output from the command, which
means it won't continue until the writing end of the pipe is closed.

But when the shell forks, there are now two file descriptors pointing
to the file object attached to the writing end of the pipe.  One is
the shell's stdout descriptor; the other is the subshell's stdout
descriptor.  The parent shell exits and closes one of these; the child
process sleeps for two seconds runs 'hostname' (which in turn inherits
the same output pointer, and writes the data the same pipe), and
exits.  When the last process holding a pointer to the writing end of
the pipe exits, the pipe is closed, and perl continues, having read
all the data.

> Any ideas what's going on here?

I hope this was clear.  There's an explanation of a similar problem at

        http://www.plover.com/~mjd/misc/dyana

> Of course, I can use fork directly...

Try this instead:

     perl -e '$x=`(sleep 2;hostname) 1>&- &`;print $x;'

The '1>&-' is shell syntax for 'please close the stdout before continuing'.
If you find that too outre; use

     perl -e '$x=`(sleep 2;hostname) >/dev/null &`;print $x;'

which tells the subshell to close its stdout (detaching it from the
pipe) and reopen /dev/null instead.

-
**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**