2010-12-11 18 views
8

STDERRSTDOUTを変数にリダイレクトしたいと思います。これは私がしました。STDOUTとSTDERRを変数にリダイレクトする方法

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

systemの問題。私はこの呼び出しの出力もキャプチャしたい。

答えて

3

出力を変数にキャプチャしようとしていますか?その場合は、適切なリダイレクトを使用してバッククックまたはqx{}を使用してください。たとえば、あなたが使用できます。

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

を(私は、ディレクトリ内のプログラムのPTH1、PTH2とpth3を持って起こる - それらがOK行われた。pth4と書き込みエラーの上には、標準エラー出力に、リダイレクトが必要でした。)

open()などの操作の成功を常に確認する必要があります。

なぜこれが必要ですか?変数への書き込みは、書き込みを行うプロセスの協力を必要とするため、makeは協力する方法を知らないためです。

2

これは、STDOUTとSTDERRの "ファイルハンドル"がではなく、シェルがperlバイナリに提供したstderrとstdoutハンドルに相当するであるためです。あなたが望むものを達成するためには、systemの代わりにopenを使用する必要があります。

+0

$ out。= qx {make};これは良い方法だとは思わない。 – Deck

+2

@イスラフィル:それを行う*方法です。 –

1

なぜかuse IPC::Open3

+0

Win32ではうまく動作しないためです。 – dolmen

0

redirect and restore STDOUTにはいくつかの方法があります。それらのうちのいくつかはSTDERRでも動作します。

selectを使用して::

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

localを使用する:

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

をお楽しみくださいここに私の2人のお気に入りです。

関連する問題