Escriba un módulo que provea una función opennp que retorna tres manejadores:
my ($fromme, $tome, $err) = opennp('metoexternal.p', 'externaltome.p', 'err.p', 'command par1 par2');
La función crea los tres pipes con nombre con los argumentos especificados lanza la 
aplicación command par1 par2 con su output redirigido a externaltome.p,
su input rederigido desde metoexternal.p y su salida de errores a err.p.
Los manejadores pueden ser entonces usados para comunicarse con la aplicación externa:
syswrite $fromme, $message;
Para lanzar el proceso de forma concurrente use fork. El seudocódigo sigue este esquema:
if ($pid = fork) { # father 
  die "Can't fork" unless defined $pid;
  ...
}
else {
  # redirect STDOUT, STDIN and STDERR  to named pipes
  exec('command par1 par2 > externaltome.p < metoexternal.p 2> err.p');
}
Lista de requisitos:
Makefile.PL con objetivo cover.
casiano@tonga:~/src/perl/pl/PL-Tutu$ cat Makefile.PL
use strict;
use warnings;
use ExtUtils::MakeMaker;
# Run 'make test' in those machines via SSH
# Install GRID::Machine for target 'remotetest'
my $REMOTETEST = 'remotetest.pl';
my $MACHINES = $ENV{MACHINES} || 'orion beowulf';
WriteMakefile(
    NAME              => 'PL::Tutu',
    VERSION_FROM      => 'lib/PL/Tutu.pm', # finds $VERSION
    PREREQ_PM         => { 'Class::MakeMethods::Emulator::MethodMaker' => 0}, # e.g., Module::Name => 1.1
    EXE_FILES         => [ 'scripts/tutu' ],
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/PL/Tutu.pm', # retrieve abstract from module
       AUTHOR         => 'Casiano Rodriguez-Leon <casiano@ull.es>') : ()),
);
sub MY::postamble {
  $_ = targets();
  s/<<REMOTETEST>>/$REMOTETEST/ge;
  s/<<MACHINES>>/$MACHINES/ge;
  return $_;
}
sub targets {
  return <<'EOSQT';
coverage:
    cover -delete
    make HARNESS_PERL_SWITCHES=-MDevel::Cover test
    cover
remotetest: dist
    <<REMOTETEST>> ${DISTVNAME}.tar.gz <<MACHINES>>
myclean: veryclean
    cover -delete
EOSQT
}
Casiano Rodríguez León
