2010-12-11 45 views
8

Tôi muốn chuyển hướng STDERRSTDOUT đến một biến. Tôi đã làm điều này.Cách chuyển hướng STDOUT và STDERR sang biến số

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. 
} 

Sự cố với system. Tôi muốn đầu ra của cuộc gọi này được bắt quá.

Trả lời

3

Bạn đang tìm cách ghi lại đầu ra trong một biến? Nếu vậy, bạn có sử dụng backticks hoặc qx{} với chuyển hướng thích hợp. Ví dụ, bạn có thể sử dụng:

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

(tôi xảy ra để có các chương trình pth1, pth2 và pth3 trong thư mục - họ đã được thực hiện OK; pth4 trở lên lỗi ghi vào thiết bị lỗi chuẩn; chuyển hướng là cần thiết.)

Bạn nên luôn kiểm tra sự thành công của các hoạt động như open().

Tại sao điều này lại cần thiết? Bởi vì việc viết cho một biến đòi hỏi sự hợp tác của quá trình thực hiện việc viết - và make không biết cách hợp tác.

2

Lý do điều này xảy ra là STDOUT và STDERR "tệp thủ công" là không tương đương với trình xử lý stderr và stdout do trình bao cung cấp cho nhị phân perl. Để đạt được những gì bạn muốn, bạn nên sử dụng open thay vì system

+0

$ out. = Qx {make}; nhưng không nghĩ đây là một cách tốt. – Deck

+2

@Israfil: đó là * cách * để thực hiện. –

1

Tại sao không use IPC::Open3?

+0

Bởi vì nó không hoạt động tốt trên Win32. – dolmen

0

Có một số cách để redirect and restore STDOUT. Một số người trong số họ làm việc với STDERR quá. Dưới đây là hai yêu thích của tôi:

Sử dụng select:

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

Sử dụng local:

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

Thưởng thức.

Các vấn đề liên quan