Come posso reindirizzare l'output da un filehandle a un altro?
-
03-07-2019 - |
Domanda
Voglio impostare una pipeline di processi all'interno di Perl (in esecuzione su Linux), composta da due parti eseguite in momenti separati.
Esempio:
Avvia il processo del consumatore:
open( OUT, "| tar xvf - " ) || die "Failed: tar: $!";
quindi molto più tardi avvia il processo di produzione:
open( IN, "gpg -d $file |" ) || die "Failed: gpg: $!";
ma in qualche modo reindirizza l'output da gpg all'input su tar.
Posso farlo costruendo un loop:
while (<IN> ) {
print OUT;
}
Ma vorrei sapere se posso in qualche modo incollare i due processi insieme al reindirizzamento.
Soluzione
Aggiungi
pipe( IN, OUT );
Prima delle due dichiarazioni aperte. Questo è tutto!
Se vuoi fare qualcosa di più complicato, consiglierei il modulo IPC :: Run CPAN:
http://search.cpan.org/dist/IPC-Run/
Ti consente di avviare i processi, collegare i loro input e output insieme e aggiungere la registrazione o il reindirizzamento in qualsiasi punto della catena.
Altri suggerimenti
Se i due processi non sono completamente correlati, utilizzare un FIFO.
use POSIX qw(mkfifo);
mkfifo($path, 0700) or die "mkfifo $path failed: $!";
Questo crea un FIFO a $ percorso. Ora fai scrivere un processo a quel file e l'altro processo letto da esso.
Mi piace Proc :: SafeExec che ti consente di collegare processi e file gestisce facilmente in modo quasi arbitrario. Ecco un esempio:
use strict;
use warnings;
use Proc::SafeExec;
open(my $ls, "-|", "ls", "-l") or die "Err: $!";
open(my $fh, ">", "tmp.txt") or die "Err: $!";
my $p = Proc::SafeExec->new({
exec => [qw(sed -e s/a/b/)],
stdin => $ls,
stdout => $fh,
});
$p->wait();
Dopo aver guardato IPC :: Run, sembra molto più semplice ... ecco lo stesso esempio usando IPC :: Run invece:
use IPC::Run qw(run);
run [qw(ls -l)], "|", [qw(sed -e s/a/b/)], ">", "tmp.txt";