antifun has asked for the wisdom of the Perl Monks concerning the following question:

Bear with me, as this is kind of convoluted.

In a Perl/Tk program I am developing, I have to spawn a child process to run in the background. (It is another, separate Perl/Tk program.) Its invocation is actually done by a shell script that checks some conditions and craps out if there are any problems. There is also the possibility that the other Perl/Tk program might fail to start. All of this needs to be logged and presented to the user in a window so they can inform our support staff about the problem.

After this point, we don't really care about the output of the child program. What we would prefer to do is just pass it through to the parent's (my) STDOUT/STDERR. Dumping it to /dev/null or closing the filehandles isn't really a viable option.

My observations about the problem:

  1. system() with a & is insufficiently capable for this because it offers no provision for capturing STDOUT/STDERR. There is also no way to know what the child pid is to see if it died (though using backticks on the backgrounded process's invocation and parsing the shell response could concievably work for this).
  2. If we fork and exec, we have to figure out how to deal with the file descriptors. Is there a way to redirect (with dup2?) an opened child's STDERR to our own without closing our STDERR? That is, merge the two? I don't know if this is possible.
  3. Assuming further that we will have to use some sort of repeater code, given that this is a Perl/Tk program, what is the easiest way to have it "automatically" echo the child's output to our own (after we have decided we don't care to watch it anymore)? I think fileevent is the way to go. Can that mechanism be used with eg. IPC::Run? I would like to minimize the amount of surgery I have to do to my application's guts to set up the repeaters, etc.

Apologies for the excessive length, and thanks in advance for any input.
---
"I hate it when I think myself into a corner."
Matt Mitchell

  • Comment on Listening to a child for a while, then passing its output along

Replies are listed 'Best First'.
Re: Listening to a child for a while, then passing its output along
by crouchingpenguin (Priest) on May 21, 2003 at 16:54 UTC

      This doesn't answer any of my questions, sadly. Here's a short version of them, restated:

      • Is there any way to "merge" file descriptors without doing any manual copying of data? That is, can you do something like
        open(CHILD_STDOUT, ">&STDOUT"); open(CHILD_STDERR, ">&STDERR");
        without screwing up the the real filehandles? (This would effect a passthrough of the child's stdout and stderr.)
      • What is the best (or a good) way to drop into an existing Perl/Tk program a routine that echoes child output as described above? Fileevents will probably work for this, but does anyone have any other ideas?

      The link you gave tells me what I already know how to do -- open a child and listen to its output. What I need to do is stop listening at some point, while letting the child continue, and echoing whatever else it says after that point to whoever might be listening to my STDOUT or STDERR.


      ---
      "I hate it when I think myself into a corner."
      Matt Mitchell
Re: Listening to a child for a while, then passing its output along
by fokat (Deacon) on May 21, 2003 at 19:21 UTC

    I think the catch here, might be to get the child to cooperate. The child could do its own close and open for the file descriptors after sending the information that the parent requires.

    Best regards

    -lem, but some call me fokat