• ベストアンサー

コンソール出力をテキストに出力する方法(コンソール出力は残しつつ)

【質問】  Perl内部で実行される実行ファイル(.exe)のコンソール出力(STDOUT,STDERR)をテキストファイルに出力したい。(Perlのコンソール出力も含む。) ※コンソール出力は残しつつ。 (コマンドプロンプトの)パイプとリダイレクトを使用して上手くいくかと思ったのですが、標準出力と標準エラーとでは標準エラーが先に出力されてしまい、本来出力される順番で出力されない。(標準出力はバッファにたまるため??) 何かいい方法はありませんでしょうか? 【環境】  Windows2000  Active Perl 5.8.8

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

CPANモジュールの File::TeeとかIO::Teeを使うというのはどうでしょうか? File::Tee - replicate data sent to a Perl stream - search.cpan.org http://search.cpan.org/~salva/File-Tee-0.03/lib/File/Tee.pm use File::Tee qw(tee); # simple usage: tee(STDOUT, '>', 'stdout.txt'); print "hello world\n"; IO::Tee - Multiplex output to multiple output handles - search.cpan.org http://search.cpan.org/~kenshan/IO-Tee-0.64/Tee.pm use IO::Tee; use IO::File; my $tee = new IO::Tee(\*STDOUT, new IO::File(">tt1.out"), ">tt2.out"); print join(' ', $tee->handles), "\n"; for (1..10) { print $tee $_, "\n" } for (1..10) { $tee->print($_, "\n") } $tee->flush;

-loki-
質問者

お礼

回答ありがとうございます。 ただ、勉強不足のため間違っていたら申し訳ないのですが、Teeモジュールを使用することで、二つ以上のハンドルに同時出力しているのだと思います。しかし、これではPerl内部で実行される実行ファイルのコンソール出力までは出力先を変更できないのではないでしょうか? 説明がわかりにくかったかと思いますので、例を記述します。以下のprint文とsystem()で出力される標準出力と標準エラーをテキストファイルに取得したいのです。(コンソール出力は残したままで) ※下の例ではエラーは発生しませんが。。 (例)  $cmd = "dir"; # 実行ファイルの代わり。 print"カレントディレクトリ内のファイルを表示 開始\n"; system($cmd); # 実際には.exeファイル print"カレントディレクトリ内のファイルを表示 終了\n"; 説明不足で申し訳ございませんでした。どなたかご教授いただけると助かります。

-loki-
質問者

補足

調べてみたのですが、File::TeeモジュールはWindowsでは使用できないみたいですね。 別の方法を検討してみます。 ありがとうございました。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ん? 手元では Windows XP + ActivePerl 5.8.6 だけど, なんとなく -------------------- ここから open(STDERR, ">&STDOUT"); print "foo\n"; print STDERR "bar\n"; system('echo "foo foo"'); system('echo "bar bar" 1>&2'); -------------------- ここまで でうまくいっている (system 内の echo も含めて全て標準出力に出ている) 感じなんですけど....

-loki-
質問者

補足

はい、コンソールには出力するんですが、テキストファイルにも同時に出力したいのです。 説明下手で申し訳ないです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

要は「標準エラーと標準出力が同じところに出ればいい」ので, open(STDERR, ">&STDOUT"); または open(STDOUT, ">&STDERR"); でなんとかなっちゃったりして.

-loki-
質問者

お礼

返事が遅くなり申し訳ございません。および意見をいただきありがとうございます。 ファイルハンドルを別のものに置き換える(関連付ける?)方法というのも考えていたのですが、system()などには反映されない模様。 sakusaker7さんに教えていただいたIO::Teeモジュールを使用して以下のようにしてみた。 #----------------------------------------------------------- (sample) use IO::Tee; my $tee = IO::Tee->new(\*STDOUT,">stdout.txt"); select(*$tee); # print文のデフォルトハンドルに設定 $cmd = "dir"; # 実行ファイルの代わり。 print"カレントディレクトリ内のファイルを表\示 開始\n"; system($cmd); # 実際には.exeファイル print"カレントディレクトリ内のファイルを表\示 終了\n"; #----------------------------------------------------------- すると。。print文の内容はコンソール・テキスト両方に出力されるのにsystem()の出力はコンソールにしか出力されない。 うーむ。。わかる方、おりましたらお教えください。 ただ、私も勉強不足が身に染みたので、しばらくしたら質問を閉めさせていただき、出直してきます。 回答をいただけた方、ありがとうございました。

関連するQ&A