• 締切済み

標準出力と標準エラー出力を時系列にファイルへ

例として、perlなどで、(test.plとします)  print "stdout1\n";  print STDERR "STDERR1\n";  print "stdout2\n";  print STDERR "STDERR2\n";  print "stdout3\n";  print STDERR "STDERR3\n"; このように、標準出力と、標準エラー出力が混在した状態の処理があった場合、 コマンドプロンプト(Windows2000)にて、 C:\>test.pl とすると、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のように時系列に出力されますが、これをログファイルに取ろうとして、 C:\>test.pl 1>log.txt 2>&1 とすると、 C:\>cat log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のように、標準エラー出力が先に吐き出されてしまいます。 これを画面出力時と同様に時系列で取れるようにしたいのですが、どのようにすれば良いでしょうか? 単純なことで困っています。よろしくお願いします。

  • goku3
  • お礼率78% (97/123)

みんなの回答

回答No.2

DOSプロンプトからプログラム出力のバッファリングを制御できる機能はないように思われます。 標準出力も標準エラー出力もコンソール以外のハンドルにリダイレクトすると、 出力内容がいったん一時ファイルに保存されてからリダイレクト先と結合するようなので 標準エラーを標準出力にリダイレクトしても時系列どおりに保存されないようです。 いろいろとパラメータを変えて試してみましたが駄目でした。 このカテゴリーよりも、技術者向けのカテゴリー (コンピューター [技術者向け] > OS > Windows系OS か その他OS)で 質問しなおせば、もしかしたら解決につながる回答が得られるかもしれません。 お役に立てずすみません。

goku3
質問者

お礼

twinkleluzさん、わざわざ調査までして頂いて、感謝いたします。 私のほうでも、UNIX-like tools からtee(.exe)を持ってきて、 >hoge.exe 2>1 | tee -a log.txt なども試してみましたが、やはり駄目でした。 画面には時系列に表示されても、ファイルへ書き込みさせると上手くいかないようです。 アドバイス頂いた通り、一度、この質問を閉じさせて頂いて、別コーナーで質問させて頂こうと思います。 取り急ぎ、お礼まで。ありがとうございました。

回答No.1

出力のバッファリングを解除すれば時系列で出力されます。 perlなら、printする前に $| = 1; とすればバッファリングされなくなります。 C言語ならsetbuf関数を使います。 その他の言語でも、"バッファリング"で検索をかければ解決策がいろいろ出てくると思います。

goku3
質問者

補足

ありがとうございました。 質問の文が良くなかったのですが、 標準出力と標準エラー出力を交互に履いているのは、 例に示したtest.plのような明示的なバッチファイルではなく、 バイナリのexeツールでした。 C:\>hoge.exe 1> log.txt 2>1& が上手く行かない。 「バッファリング」でgoogleって探してみましたが、今一つ見つけられませんでした。 MS-DOSとして、バッチ処理前にバッファリングをOFFにする方法などは無いでしょうか。よろしくお願いします。

関連するQ&A

  • 標準出力/標準エラー出力を時系列にファイルへ

    画面への文字出力が、標準出力(stdout)と標準エラー出力(stderr)の 両方もつような、コンソールアプリ(exe形式)のツールを動作させたときに、 画面上には、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のような順番で処理順にメッセージが出るのですが、 これをファイルに落とそうとして、  C:\>hoge.exe 1> log.txt 2>1& とすると、log.txtの中身が、 C:\>type log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のような標準エラー出力が先に吐き出される順番になってしまっています。 これを、exe実行前に、MS-DOSとして何らかの設定を行うことで、 ファイルに落とした時も、出力された文字が時系列に保存されるように する方法はあるでしょうか? よろしくお願いします。

  • 標準出力と標準エラー出力を変数にセットしたいです。

    始めたばかりの初心者の為、変な質問でしたら申し訳ありません。 標準出力と標準出力を別々の変数にセットしたいのですが、そのやり方が分からず困っています。 やりたいことは、 コマンド(diffやcatなどの)実行結果の標準出力と標準エラー出力を それぞれ「任意の文字_受取パラメータの値」にセットすることをしたいです。 下記は、1回ファイルに出力して、それを読んで変数にセットするように記述したものです。 ※記述間違っていたらすみません。 ファイルに書かなくても、パイプやその他コマンドなどで出来る方法はないでしょうか? ex) test.sh 1.txt 2.txt TEST01 で実行 #!/bin/sh parm1 = $1 parm2 = $2 parm3 = $3 diff "${parm1}" "${parm2}" > test.log 2> err.log eval w_stdout_${parm3}=¥`cat test.log¥` eval w_stderr_${parm3}=¥`cat err.log¥` eval echo "stdout:¥"¥{w_stdout_${parm3}}¥"" eval echo "stderr:¥"¥{w_stderr_${parm3}}¥"" ※実行した結果 stdout:diff結果 stderr:空白 お手数ですが、何卒宜しくお願い致します。

  • PHP5の外部コマンド実行で、バッチファイルのエラーレベル値と標準出力(標準エラー?)の3つを取得できる関数はありますか?

    PHP5のWindows版を使っています。 外部コマンドを実行して、Windowsのバッチファイルのエラーレベル値と標準出力(標準エラー?)の3つを取得できる関数はありますか? test.cmdの中味 echo 標準出力内容です。 echo バッチファイルで標準エラー出力はわかりませんが exit /b 2 list ($ret, $stdout, $stderr) = 何か関数("test.cmd") echo $ret; // 2 echo $stdout; // 標準出力内容です。\nバッチファイルで標準エラー出力はわかりませんが echo $stderr; // ???? よろしくお願い致します。

    • ベストアンサー
    • PHP
  • Cシェルで標準エラー出力への出力方法を教えてください。

    Cシェルにおいて、通常echo文は標準エラー出力へ表示されます。 echo文のように引数で指定した文字列を標準エラーとして出力するような コマンド?があったら教えてください。 c言語では fprintf(stderr,"test!\n"); などとやりますが、Cシェルではありますでしょうか?

  • 標準出力上でのファイルポインタの扱いで困っています。

    標準出力上でのファイルポインタの扱いで困っています。 簡単な例で説明すると、 下のプログラムはファイル内で、一秒ごとに左から順に1を0で置き換えていくもので正常に動作します。 open(F, '+< temp'); print F "11111111111111111111111111111111\n"; for(0..31){ seek(F, $_, 0); print F '0'; sleep(1); } close(F); 同様のことが標準出力でも可能かと思って以下のようにしてみたのですが、うまくいきません。 open(STDOUT, '+<'); print STDOUT "11111111111111111111111111111111\n"; for (0..31){ seek(STDOUT, $_, 0); print STDOUT '0'; sleep(1); } close(STDOUT); } 2つ目の例では動作を見るかぎり、ファイルポインタは1111.....の先頭からのオフセットではなく、その次の行(空行)の先頭からのオフセットとなっているように見えます。つまり古い行には戻れていないようです。 Seek()は標準出力上では使えないのでしょうか?

    • ベストアンサー
    • Perl
  • 標準出力、標準エラー出力 以外の出力??

    Linux上のCADツールが端末に出力してくる文字列をファイルに落とすことができないで困っています。 どのようなことが起きているのでしょうか? また、このような場合、どのようにしたら端末上に流れる文字をすべてファイルとして保存できるのでしょうか。 %> CAD_TOOL.exe |& tee log として標準出力、標準エラー出力の両方をlogというファイルにおとしたつもりなのですが、画面に流れたすべての文字列が保存されている訳ではないのです。 Linuxの出力には標準出力と標準エラー出力の2つ(だけ)がある[*]、と思っていましたが他の出力方法があったりするのでしょうか。。。 [*]http://x68000.q-e-d.net/~68user/unix/pickup?%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8 宜しくお願いします。

  • 標準出力しながらファイルに出力

    標準出力に表示したものを、そのままファイルに書き込むことは可能でしょうか? 例えば下記のように実現できるかと思いますが、printする度に2行書くのは厳しく思ってます。 ----------------------------- open(OUT, "> outfile.txt") ; print $aaa ; print OUT $aaa ; -----------------------------

  • stdout/stderrを同一ファイルに出力

    シェルのレベルでは単に: exec >> stdouterr.log 2>&1 とするだけで、2つのストリームを1つのファイルに出力できるようです。 ところがこれをC言語で実現することができません。例えば次のコード: FILE *fpout, *fperr; setbuf ( stdout, 0 ); setbuf ( stderr, 0 ); fpout = freopen( "outfile", "wb", stdout ), fperr = freopen( "outfile", "wb", stderr ); printf ( "処理を開始します。\n\n\n" ); fprintf(stderr, "stderrに出力します。\n" ); Msg = K_Link.LnkConvert (); printf ( "\n\n\n処理を完了しました。\n\n\n" ); fclose ( fpout ); fclose ( fperr ); を実行すると、下記のような『outfile』ができてしまいます。 処理を開始します。 MS-DOSコマンド"mkdir /public1/public/Pic/Compile_euc/K_LIB"を実行します。 MS-DOSコマンド"cp -r /public1/publ....../K_LIB/* /publ.../K_LIB"を実行します。 MS-DOSコマンド"chmod -R u+rw /public1/pu.._euc/K_LIB"を実行します。 ファstderrに出力します。 <-<-<-<-<-<-<-<-<-<-<-<-<-<-<- 何か変? Pic/Compile_euc/tmp.dat"をファイル"/public1/p..._LIB/Makefile"にコピー。 ファイル"/pub...p.dat"をファイル"/public....ile.gcc"にコピー。 | | | | | | | | | | の様に出力が壊されてしまいます。 2つのストリームからデータが出力されるタイミングがそれぞれ異なるようです。 どの様にしたらうまくいくのか助言ください。

  • ファイルの3行目までを出力したい

    Perl初心者です。 test.txtというファイルがあって、その中の1行目から3行目までを 出力したい場合はどうしたらいいでしょうか? open(FILE,"test.txt") || die "Open Error.\n"; @data = <FILE>; close(FILE); foreach (@data) { print $_; } これだと、ファイルの中身が全て出力されてしまいます。

    • ベストアンサー
    • Perl
  • warnやdieの出力先を変更したい

    お世話になります。 現在perlを勉強しているのですが(ActivePeal5.12.2) コマンドプロンプトから test.pl > test.log と実行した場合、test.pl内で標準出力した文字列がtest.logにリダイレクトされますが test.pl内で ~die "ERROR~"とした場合、"ERROR~"はtest.logに出力されません。 これを簡単にtest.logに出力する方法はないでしょうか。 リダイレクトせず実行した場合、画面に出力されているのでリダイレクトすればそのまま良いと思っていたのですが・・

    • ベストアンサー
    • Perl