Hi, these following codes have been posted before in some lost node numbers. But here is the way to do it:
Also see
Fork and wait question. You can setup 2 way pipes too, so you can have bi-directional communication between
parent and child.
#!/usr/bin/perl
use warnings;
use strict;
#piping all child output to parent
# by Zaxo of perlmonks
# we'll define some subroutiness to act as children
# and open a single pipe.
my @kids = (
sub { print "First!", $/; },
sub { print "Second!", $/; },
sub { print "Third!", $/; },
);
pipe my ( $in, $out );
# Now we start breeding children. Each will close the $in handle,
# select the $out handle as the default, set up autoflush on it,
# and then call their sub. We definitely need to prevent zombies,
# since the kids will all finish before the parent does, so we
# start by declaring a hash where we will keep their pid's.
my %kid;
for (@kids) {
my $cpid = fork;
defined $cpid or warn("Couldn't fork"), next;
$cpid or do { # child
close $in or die $!;
select $out;
$| = 1;
$_->();
exit 0;
};
$kid{$cpid} = undef;
}
# The select statement is the one-arg kind, which windows should
# handle ok. Back in the parent, now, we have an unwanted $out handle,
# a single $in handle that the kids are all fighting to talk on, and
# a hash to remind us of the kids' names. Wrapping up, we close $out,
# listen to the kids in turn, decorate their messages to show
# who's repeating them, and finally call wait enough times to
# bury them all safely. We must be careful not to die before that.
close $out or warn $!;
s/.$/??? says the child/, print while <$in>;
delete $kid{ +wait } while %kid;
# Many-to-one pipes like this will keep their messages' integrity
# in flush-sized chunks. So long as they are shorter than than
# an I/O buffer and end with $/, they will be read as distinct.
# You may want to have the kids tag their messages to
# identify the source.
# I've tested this on Windows XP and Linux. It works on both.
or simpler, pipe all output to parent
#!/usr/bin/perl
use strict;
use warnings;
my $pid = open(CHILD, "-|");
if ($pid)
{
# parent
print "parent got:\n";
print while(<CHILD>);
close CHILD; # this waits on child
}
elsif ($pid == 0)
{
# child
print "kid here!\n";
exec '/bin/date' or die "Can't exec date $!\n";
}
else
{
die "fork error: $!\n";
}