This program runs a simple program in the background and collects its
output. It's possible to interact with child programs as well.
#!/usr/bin/perl
use warnings;
use strict;
use POE qw( Wheel::Run Filter::Line );
# Start the session. Spawn a simple program, and describe the events
# it will generate as it does things.
sub _start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
$heap->{child} = POE::Wheel::Run->new(
Program => ["/bin/ls", "-1", "/"], # Program to run.
StdioFilter => POE::Filter::Line->new(), # Child speaks in lines.
StderrFilter => POE::Filter::Line->new(), # Child speaks in lines.
StdoutEvent => "got_child_stdout", # Child wrote to STDOUT.
StderrEvent => "got_child_stderr", # Child wrote to STDERR.
CloseEvent => "got_child_close", # Child stopped writing.
);
$kernel->sig_child($heap->{child}->PID, "got_sigchld");
}
# Deal with information the child wrote to its STDOUT.
sub got_child_stdout {
my $stdout = $_[ARG0];
print "STDOUT: $stdout\n";
}
# Deal with information the child wrote to its STDERR. These are
# warnings and possibly error messages.
sub got_child_stderr {
my $stderr = $_[ARG0];
$stderr =~ tr[ -~][]cd;
print "STDERR: $stderr\n";
}
# The child has closed its output filehandles. It will not be sending
# us any more information, so destroy it.
sub got_child_close {
my $heap = $_[HEAP];
print "child closed.\n";
delete $heap->{child};
}
# Handle SIGCHLD, otherwise the child process will not be reaped.
# Don't do anything significant, but do catch the signal so the child
# process is reaped.
sub got_sigchld {
print "SIGCHLD reaped.\n";
}
# A list of functions that will handle the events they're named after.
my @handlers = qw(
_start got_child_stdout got_child_stderr got_child_close
got_sigchld
);
# Start a session where each event is handled by a function with the
# same name. Run POE's Kernel (and thus all its sessions) until done.
POE::Session->create(package_states => [main => \@handlers]);
POE::Kernel->run();
exit 0;