Comment puis-je rediriger la sortie d'un descripteur de fichier vers un autre?
-
03-07-2019 - |
Question
Je souhaite configurer un pipeline de processus à partir de Perl (fonctionnant sous Linux), composé de deux parties exécutées à des moments différents.
Par exemple:
Démarrer le processus consommateur:
open( OUT, "| tar xvf - " ) || die "Failed: tar: $!";
puis, beaucoup plus tard, démarrez le processus de production:
open( IN, "gpg -d $file |" ) || die "Failed: gpg: $!";
mais redirigez d'une manière ou d'une autre la sortie de gpg dans l'entrée vers tar.
Je peux le faire en construisant une boucle:
while (<IN> ) {
print OUT;
}
Mais j'aimerais savoir si je peux en quelque sorte coller les deux processus avec la redirection.
La solution
Ajouter
pipe( IN, OUT );
Avant les deux déclarations ouvertes. C'est ça!
Si vous voulez faire quelque chose de plus compliqué, je vous recommande le module IPC :: Run CPAN:
http://search.cpan.org/dist/IPC-Run/
Il vous permet de démarrer des processus, de lier leurs entrées et leurs sorties et d'ajouter une journalisation ou une redirection à n'importe quel point de la chaîne.
Autres conseils
Si les deux processus n'ont aucun lien, utilisez une FIFO.
use POSIX qw(mkfifo);
mkfifo($path, 0700) or die "mkfifo $path failed: $!";
Ceci crée une FIFO à $ path. Désormais, un processus écrit dans ce fichier et l’autre le lit.
J'aime Proc :: SafeExec , car il vous permet de lier des processus et des fichiers. gère de manière presque arbitraire facilement. Voici un exemple:
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();
Après avoir examiné IPC :: Run, cela semble beaucoup plus simple ... voici le même exemple utilisant IPC :: Run à la place:
use IPC::Run qw(run);
run [qw(ls -l)], "|", [qw(sed -e s/a/b/)], ">", "tmp.txt";