Rubyプログラム中の標準出力を表示しながら取得する方法

このQ&Aのポイント
  • Rubyプログラム中の標準出力を表示しながら取得する方法を知りたいです。
  • 現在、Ruby初心者ですが、プログラム中の標準出力を通常の出力も表示しながら取得したいと考えています。
  • 標準出力を取得する方法として、capture_stdoutメソッドを見つけましたが、ブロック内の出力結果は取得できません。最終的な出力結果を取得する方法はありますか?
回答を見る
  • ベストアンサー

rubyプログラム中の標準出力を表示しながら取得し

ruby初心者です。 プログラム中の標準出力を、通常の出力も表示しながら取得したいと考えています。 自分でもいろいろ調べてみたのですが、 標準出力を取得する以下のようなコード ======================================================== # ブロック内の標準出力を取得する def capture_stdout out = StringIO.new $stdout = out yield return out.string ensure $stdout = STDOUT end (ttp://blog.livedoor.jp/sonots/archives/33344291.html) ================================================= は見つけたのですが、 これだと出力結果は、 capture_stdoutのブロックが終了しないことには取得できません。 capture_stdoutの中のブロック内プログラムの出力をコンソールに表示しながら、 最後に出力結果も取得したいのですが、 何か方法はあるのでしょうか? 教えてください。

  • Ruby
  • 回答数2
  • ありがとう数13

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.2

こんな感じで class MySTDOUT < IO def initialize(file) @f = File.open(file,"w") super(1,"w") end def close @f.close super end def write(str) @f.write(str) super end end $stdout=MySTDOUT.new("1234.txt") p [1,2,3,4,5] puts "This is a pen."

okwaver85758
質問者

お礼

回答有難うございます。 勉強になりました。

その他の回答 (1)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

OSが不明なのですが、linux等のunix系であれば以下のようにします。 ruby あなたのスクリプト名 上記のコマンドを実行すると、実行結果が画面に表示されますが、 表示すると同時に、ファイルに書き込むには tee コマンドを使用します。 ruby あなたのスクリプト名 tee log.txt とすると log.txtに画面に表示された内容とおなじものが書き込まれます。

okwaver85758
質問者

お礼

回答有難うございます。 できればプログラム側で行いたいのですが、 何か方法はありますでしょうか?

関連するQ&A

  • Rubyから外部プログラムを実行し、その出力を..

    Rubyから外部プログラムを実行し、その出力を受け取り、加工したいのですがよくわかりません。 stdin, stdout, stderr = win32-open3.popen3("XXX.exe") とすれば何とかいけそうなんですが、win32-open3が今は使われていないようです。 他に代わるものがあるのでしょうか? ちなみに、Rubyのバージョンは1.8.7です。 よろしくお願いします。

    • ベストアンサー
    • Ruby
  • system で実行したプログラムの標準出力を変数で受け取りたい

    実行結果を標準出力に出力する cプログラム A があります。 perl から system を利用して A 呼び出し、その実行結果を perl で加工する仕組みを考えています。 今のところ、標準出力を一旦変更して、テンポラリのファイルに出力させ、再度そのファイルをオープンして perl で利用するという形で何とか実現できています。 open (SAVESTDOUT, ">&STDOUT") or die "..."; #(1) open (STDOUT, ">$tempFile") or die "..."; #(2) system "A"; #(3) close(STDOUT) or die "..."; #(4) open(STDOUT, ">&SAVESTDOUT") or die "..."; #(5) という感じです。 一旦テンポラリーのファイルを介するところがスマートでないので、直接変数に標準出力結果を落したいです。 (1) そのまま (2) 標準出力を perl の変数に変更 (3) そのまま (4) なし (5) そのまま といった感じで実現したい(もちろんより良い解法があれば尚宜しいです)のですが、可能でしょうか? ご教授ください。宜しくお願いします。

    • ベストアンサー
    • Perl
  • Rubyのpopen3について

    はじめまして Rubyをはじめて1か月の初心者です。 popen3を使用するにあたって大変困っております。 popen3で外部コマンドを実行して、実行結果の標準出力をファイルとして格納しようと思っています。 外部コマンドの内容は、SSH接続でサーバへログインし、そこにあるシェルスクリプトを実行させるもので、 呼び出すシェルスクリプトに対して、Rubyから標準入力を渡し、シェルスクリプトが標準入力を受け取り、 それをもとに呼び出したシェルスクリプトがさらに別のシェルスクリプトを呼び出し、実行結果を標準出力としてRubyで受け取ってファイルに格納したいと思っています。 ソースとしては、以下のようにしてますが、標準入力を引き渡す方法が分かりません。 その為、標準入力を引き渡す部分は記述していません。 Open3.popen3('ssh localhost sh test.sh ') do |stdin, stdout, stderr|   begin    loop do     IO.select([stdout,stderr]).flatten.compact.each { |io|      if stdout != "" then       stdout_lines = stdout        puts("stdout_lines = " + stdout_lines)      end      stderr_lines = stderr if stderr != ""      puts("stderr_lines = " + stderr_lines)     }     break if $stdout.classed? && $stderr.closed?   end   rescue EOFError   end end JRubyの1.6.8なので、Rubyのバージョンは1.8.7相当です。 なにぶん初心者の為、なにをどうすれば良いか分からない状態です。 まず、実現が可能かを知りたいです。 実現可能であれば、標準入力を引き渡す方法を教えていただきたく。 よろしくお願いします。

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

    始めたばかりの初心者の為、変な質問でしたら申し訳ありません。 標準出力と標準出力を別々の変数にセットしたいのですが、そのやり方が分からず困っています。 やりたいことは、 コマンド(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:空白 お手数ですが、何卒宜しくお願い致します。

  • Rubyを使ってtelnetで実行したコマンドの標準出力を取得したいのですが…

    Rubyを使って、以下のような手順のプログラムを作成しています。 1.Telnetでサーバ(Fedora7)にログイン 2.ifconfigを実行 3.標準出力される結果をファイルに記録 次のように試してみたのですが、結果をファイルに記録することが、できないでいます。 require 'net/telnet' log = File.open("ifconfig.log",'a+') # リモートホスト foobar に接続 telnet = Net::Telnet.new("Host" => "192.168.1.1") {|c| print c} telnet.login("username", "password") {|c| print c} telnet.cmd("ifconfig"){|c| log.print(c)} log.close 標準出力される結果をファイルに記録する方法を知っているかたがおられましたら、教えていただけませんでしょうか。 宜しくお願いいたします。

  • RubyプログラムでURLより取得したデータの出力

    Rubyにて、Twitterの出力結果をスクリプト経由で出力させるさせようとしていますが、日本語で出力させたいのですが、出力結果が下記のように文字化けしてしまうのですが、日本語として表示させることは可能でしょうか。-K kcodeオプションは試したのですが結果は変わりませんでした。 ご存知の方がいらっしゃれば、ご教示お願いいたします。 "description"=> "\u901A\u4FE1\u4E8B\u696D\u8005\u304B\u3089\u6D41\u308C\",

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

    標準出力上でのファイルポインタの扱いで困っています。 簡単な例で説明すると、 下のプログラムはファイル内で、一秒ごとに左から順に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
  • Rubyのイテレータ

    Rubyのイテレータで分からないところがあります。以下のコードです。 if文のところで「yield x」が真なら「return x」を実行すると 推測できるのですが、 その実行結果はこれです。 > irb> a = [1, 2, 3, 4, 5] > => [1, 2, 3, 4, 5] > irb> find(a) {|x| x % 2 == 0} > => 2 > irb> position(a) {|x| x % 2 == 0} > => 1 > irb> count(a) {|x| x % 2 == 0} > => 2 例えば、find関数なら引数は「x」ですが「x % 2 == 0」 と条件式をブロックに書いているのが分かりません。 全体の流れとしてはfind関数なら2で割り切れたのが「2」と「4」で2つあるので 関数の結果は「2」というのは理解できます。 しかし、具体的に「return x」「 if yield x」が何をしているのかが分かりませんでした。 if「もし」yield x「なら」return xを実行する、様なコードなのですが・・・。 またfind(a)なら、引数xが2で割り切れるのなら条件式は「真」なので 真の数字をカウントする、様なコードなのですが・・・。それ以上詳細に教えてくれると助かります。 何方かご存知でしたら教えてください。 > リスト 1 : データの探索 (イテレータ版) > > # ブロックが真となる要素を探す > def find(ary) > for x in ary > return x if yield x > end > false > end > > # ブロックが真となる要素の位置を返す > def position(ary) > for x in 0...ary.size > return x if yield ary[x] > end > false > end > > # ブロックが真となる要素の個数を求める > def count(ary) > c = 0 > for x in ary > c += 1 if yield x > end > c > end なおこのコードが載っているサイトはここです。 http://www.geocities.jp/m_hiroi/light/abcruby08.html

    • ベストアンサー
    • Ruby
  • 外部コマンドを使用しない標準出力の取得方法を教えて下さい

    外部コマンドを使用しない標準出力の取得方法を教えて下さい いつもお世話になっています。 javaのプログラム内で、その直前の標準出力を取得する方法がわかりません。「標準出力 取得」などで検索しても、外部プロセスがらみ(Runtime.getRuntime().exec(xxx)のprocessからストリームを取得など)の事ばかりがヒットしてしまいます。 やりたい事はもっと単純で、標準出力をするメソッドを呼び出した後に、そのメソッドが標準出力した内容を取得したいのです。 以下のコードのコメントの箇所の、具体的な実装方法を知りたいのです。この例では簡単のために、標準出力するメソッドを同一クラス内のメソッドとしていますが、本当は別のクラスのメソッドで、もちろん標準出力の内容は実行時までわかりません。 public class hello {   public static void main (String[] args) {     sub();     // sub()で標準出力した内容をここで取得したい!   }   private static void sub(){     System.out.println("Hello World !!");   } }

    • ベストアンサー
    • Java
  • 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

専門家に質問してみよう