2010-12-11 21 views
8

Chcę przekierować STDERR i STDOUT do zmiennej. Ja to zrobiłem.Jak przekierować STDOUT i STDERR do zmiennej

close(STDOUT); 
close(STDERR); 

my $out; 
open(STDOUT, ">>", \$out); 
open(STDERR, ">>", \$out); 

for(1..10) 
{ 
    print "print\n"; # this is ok. 
    warn "warn\n"; # same 
    system("make"); # this is lost. neither in screen nor in variable. 
} 

Problem z system. Chcę, aby wychwycono również wyjście tego połączenia.

Odpowiedz

3

Czy chcesz przechwycić dane wyjściowe w zmiennej? Jeśli tak, użyj wstecznego kliknięcia lub qx{} z odpowiednim przekierowaniem. Na przykład, można użyć:

#/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"; 
} 

(zdarza mi się mieć programy pth1, PTH2 i pth3 w katalogu - zostały one wykonane OK; pth4 i powyżej błędów zapisu do stderr; przekierowanie było konieczne.)

Powinieneś zawsze sprawdzić sukces operacji, takich jak open().

Dlaczego jest to konieczne? Ponieważ pisanie do zmiennej wymaga współpracy procesu pisania - i make nie wie, jak współpracować.

2

Dzieje się tak dlatego, że uchwyty plików STDOUT i STDERR są , a nie równoważne do uchwytów stderr i stdout dostarczanych przez powłokę do pliku binarnego perl. Aby uzyskać to, czego chcesz, powinieneś użyć open zamiast system

+0

$ out. = Qx {make}; działa, ale nie sądzę, że to dobry sposób. – Deck

+2

@Israfil: jest to * sposób na zrobienie tego. –

1

Dlaczego nie use IPC::Open3?

+0

Ponieważ nie działa dobrze na Win32. – dolmen

0

Istnieje kilka sposobów na redirect and restore STDOUT. Niektóre z nich również współpracują ze STDERR. Oto moje dwa ulubione:

Korzystanie select:

my $out; 
open my $fh, ">>", \$out; 
select $fh; 
print "written to the variable\n"; 
select STDOUT; 
print "written to original STDOUT\n"; 

Korzystanie local:

my $out 
do { 
    local *STDOUT; 
    open STDOUT, ">>", \$out; 
    print "written to the variable\n"; 
}; 
print "written to original STDOUT\n"; 

cieszyć.

Powiązane problemy