# Something like this: use IO::Select; my $bladeenc_cmd = 'bladeenc -whatever args'; my $cdparanoia_cmd = 'cdparanoia -whatever else args'; open P1, "$bladeenc_cmd|" or die "bladeenc: $!"; open P2, "$cdparanoia_cmd|" or die "cdparanoia: $!"; local $SIG{PIPE} = sub { warn "pipe closed"; } my $s = IO::Select->new(); my $timeout = 100; # msec(?) $s->add(\*P1); $s->add(\*P2); my @ready; while (@ready = $s->can_read($timeout)) { foreach my $fh (@ready) { if ($fh == \*P1) { my $line = <$fh>; # write to first window } if ($fh == \*P2) { my $line = <$fh>; # write to second window } } } # you get the idea ...