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

Hi

I have a perl script that:
   - reads STDIN line by line and for each line:
      - parses the line ( in order to build a list of system commands)
      - writes the line to STDOUT
      - writes the line out to an output file
   - forks a child to run each system command in the list
( the relevant parts of the code are below ) at the completion of this script, I would expect that the input file would have been written as is to STDOUT and the output file... howver I find that the output file contains the input file repeated many times - although it is only written once to STDOUT.
If I take the forking code out ( no pun intended) then I only get once copy of the input file in the output file.
Whats going on here? and why doesnt it happen with STDOUT?

Thanks Kung

open(MFOUT,">mfout.txt"); while (<STDIN>) { print MFOUT $_; print $_; <SNIP> ... stuff that builds up commands in @commands... ... eg 'perl anotherscript.pl < input' </SNIP> } my %running = (); my $max_jobs = 200; my $job_count = 0; while ( @commands || %running ) { if ( @commands && ($job_count < $max_jobs)) { my $command = shift(@commands); my $pid; if ($pid = fork) { print "Parent Pid $$\n"; $running{$pid} = $command; ++$job_count; } else { die "cannot fork: $!" unless defined $pid; print "Child Pid $$ $command\n"; my $rc = system $command; exit($rc>>8); } } else { my $child_pid = wait(); if (! exists $running{$child_pid}) { warn "Reaped unkown process id $child_pid!!"; } elsif ($?) { my $rc = $? >> 8; warn "Process '$child_pid:$running{$child_pid}' errored with retu +rn code '$ rc'"; } print "command '$running{$child_pid}' completed\n"; delete $running{$child_pid}; --$job_count; } }

Edit: chipmunk 2001-05-16

Replies are listed 'Best First'.
Re: fork and print..
by chipmunk (Parson) on May 17, 2001 at 18:30 UTC
    Try closing MFOUT before you fork: close(MFOUT); This should flush the contents of the output buffer, which otherwise would get duplicated in all of the children.

      And probably the reason this code works for jepri and not for Kung is that newer Perls (5.6) auto flush buffers before forking (on many platforms).

              - tye (but my friends call me "Tye")
Re: fork and print..
by jepri (Parson) on May 17, 2001 at 09:00 UTC
    I just ran your code with some arbitrary commands in @commands and it works fine. So the problem is with the code that you cut out before you posted, not with what's here.

    If you post the other routine we will be able to help you to debug that too.

    Update: I'm running perl5 (revision 5.0 version 6 subversion 0)

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      hmmmm.... curiouser and curiouser...

      I just did the same thing as jepri and it still DIDNT work!!????

      This suggests to me that something about my installation is broken - I am running Perl version 5.004_04 built for sun4-solaris on SunOS 5.6 - Does anyone know what could cause a problem like this with this config?

      just in case here is the exact code I ran and the results:

      open(MFOUT,">mfout.txt"); while (<STDIN>) { print MFOUT $_; print $_; } my @commands = ("ls","ls *","cat a","cat x"); my %running = (); my $max_jobs = 200; my $job_count = 0; while ( @commands || %running ) { if ( @commands && ($job_count < $max_jobs)) { my $command = shift(@commands); my $pid; if ($pid = fork) { print "Parent Pid $$\n"; $running{$pid} = $command; ++$job_count; } else { die "cannot fork: $!" unless defined $pid; print "Child Pid $$ $command\n"; my $rc = system $command; exit($rc>>8); } } else { my $child_pid = wait(); if (! exists $running{$child_pid}) { warn "Reaped unkown process id $child_pid!!"; } elsif ($?) { my $rc = $? >> 8; warn "Process '$child_pid:$running{$child_pid}' errored with retu ++rn code ' $rc'"; } print "command '$running{$child_pid}' completed\n"; delete $running{$child_pid}; --$job_count; } }
      when I ran this with input:
      line1
      line2
      line3
      line4

      I got the same output on STDOUT, but mfout.txt contained:
      line1
      line2
      line3
      line4
      line1
      line2
      line3
      line4
      line1
      line2
      line3
      line4
      line1
      line2
      line3
      line4
      line1
      line2
      line3
      line4
        woops - forgot to log in - that anonymous monk above is me :)