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

Hi monks, I have a script which forks a child and exec's another program. The parent script then generates signals to the running child exec. My question is, how can I get a stdout line from the child immediatly in the parent script? And how do I tell in the parent script when the child has finished? I want to do something like this:
my $child = fork; if (!$child) { exec('someprogram.exe'); exit; } else { while (child_process_still_running()) { sleep 1; system('kill -USR1 $child'); #signal child get_new_std_out_lines_child_has_printed_inresponse_to_signal(); } }

Replies are listed 'Best First'.
Re: Get live output of exec
by kennethk (Abbot) on Mar 04, 2014 at 01:00 UTC
    As LanX wisely says, read perlipc. Every topic below is discussed, in more detail and with examples.
    The parent script then generates signals to the running child exec
    Communicating via STDIN to the child would probably be easier than signals. Like in IPC::Open2.
    how can I get a stdout line from the child immediatly in the parent script?
    If you are piping (which you need to do if you are running via exec), you need to turn on autoflush. See IO::Handle or $| and select.
    And how do I tell in the parent script when the child has finished?
    kill can test if the executable is still running (kill(0, $pid)). wait or waitpid can be used to reap the child. IO::Select or eof can be used to check if the child has something to say.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Get live output of exec
by LanX (Saint) on Mar 03, 2014 at 23:50 UTC
Re: Get live output of exec
by zentara (Cardinal) on Mar 04, 2014 at 12:02 UTC
    I would create a set of pipes, using IO::Pipe between the parent, and the child, and have the child send immediately to the parent with autoflush turned on.

    Here is a simple example( not using IO::Pipe ).

    #!/usr/bin/perl use warnings; use strict; use IO::Handle; $|++; pipe( PARENT_READER, CHILD_WRITER ); pipe( CHILD_READER, PARENT_WRITER ); PARENT_WRITER->autoflush(1); CHILD_WRITER->autoflush(1); my $pid; if ( $pid = fork() ) { close(CHILD_READER); close(CHILD_WRITER); my $buffer; print PARENT_WRITER 1; while (1) { sysread( PARENT_READER, $buffer, 100 ); print "parent revd: $buffer, and reply with ", $buffer + 1, "\ +n"; sleep(1); print PARENT_WRITER $buffer + 1; } } else { close(PARENT_READER); close(PARENT_WRITER); my $buffer; while (1) { sysread( CHILD_READER, $buffer, 1000 ); print "child revd: $buffer, and reply with ", $buffer + 1, "\n +"; sleep(1); print CHILD_WRITER $buffer + 1; } }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      > Here is a simple example( not using IO::Pipe ).

      You are confusing me... :)

      Are there special reasons for recommending this module except its OO interface?

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        Never used it, but the docs certainly look like it makes clean-up a whole lot easier. Cute misdirection so you don't have to remember the argument order on the constructor. Looks like it's been in CORE since 5.12.


        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.