Je souhaite rediriger STDERR
et STDOUT
vers une variable. J'ai fait ça. Le problème avec system
. Je veux que la sortie de cet appel soit capturée aussi.Comment rediriger STDOUT et STDERR vers une variable
Répondre
Cherchez-vous à capturer la sortie dans une variable? Si c'est le cas, vous devez utiliser des guillemets ou qx{}
avec la redirection appropriée. Par exemple, vous pouvez utiliser:
#/usr/bin/env perl
use strict;
use warnings;
# Ensure we have a way to write messages
open my $fh, '>', "output" or die;
close(STDOUT);
close(STDERR);
my $out;
open(STDOUT, ">>", \$out) or do { print $fh, "failed to open STDOUT ($!)\n"; die };
open(STDERR, ">>", \$out) or do { print $fh, "failed to open STDERR ($!)\n"; die };
foreach my $i (1..10)
{
print "print $i\n";
warn "warn $i\n";
my $extra = qx{make pth$i 2>&1};
print $fh "<<$i>><<$out>><<$extra>>\n";
}
(j'arrive d'avoir des programmes PTH1, PTH2 et pth3 dans le répertoire - elles ont été faites OK, pth4 et au-dessus des erreurs d'écriture à stderr, la redirection était nécessaire.)
Vous devez toujours vérifier le succès des opérations telles que open()
.
Pourquoi est-ce nécessaire? Parce qu'écrire à une variable nécessite la coopération du processus en faisant l'écriture - et make
ne sait pas comment coopérer.
La raison pour laquelle cela se produit est que les "handles de fichiers" STDOUT et STDERR sont et non équivalent aux handles stderr et stdout fournis fournis par le shell au binaire perl. Afin d'obtenir ce que vous voulez, vous devez utiliser open au lieu de system
utilisez Capture::Tiny!
Il existe plusieurs façons de redirect and restore STDOUT. Certains d'entre eux travaillent avec STDERR aussi. Voici mes deux favoris:
Utilisation select
:
my $out;
open my $fh, ">>", \$out;
select $fh;
print "written to the variable\n";
select STDOUT;
print "written to original STDOUT\n";
Utilisation local
:
my $out
do {
local *STDOUT;
open STDOUT, ">>", \$out;
print "written to the variable\n";
};
print "written to original STDOUT\n";
Profitez.
$ out. = Qx {make}; fonctionne mais ne pense pas que c'est un bon moyen. – Deck
@Israfil: c'est * la * façon de le faire. –