• 締切済み

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相当です。 なにぶん初心者の為、なにをどうすれば良いか分からない状態です。 まず、実現が可能かを知りたいです。 実現可能であれば、標準入力を引き渡す方法を教えていただきたく。 よろしくお願いします。

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

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

shellからの出力を、Rubyで入力として受けとってますよね? shellの入力に渡すには、その逆で、Rubyから出力してやればいいのです。 シェルから続けて別なコマンドに渡すには 方法1) パイプライン込みのコマンドラインを popen3の引数として指定する Open3.popen3('sh test.sh | sh test2.sh') 方法2) Rubyでパイプラインの代りをする Open3.popen3('sh test.sh') #A Open3.popen3('sh test2.sh') #B Aの出力をRubyで入力し、Bの入力へとRUbyから出力する。

yasuhira1011
質問者

補足

test.shに対して、標準入力を引き渡す方法が分かりました。 以下のように、Open3.popen3のdoの最初にstdinに対してデータをWriteしてあげれば、 シェルの方で、『cat -』 をすれば標準入力が取得できました。 説明が下手でちゃんと伝えられませんで、すみません。 色々読み取っていただきありがとうございます。 Open3.popen3('ssh localhost sh test.sh ') do |stdin, stdout, stderr|   stdin.write(data1)   #標準入力のクローズ   stdin.close   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

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

マニュアル、読んでますか? サンプルコードもけっこう載ってますよ http://doc.ruby-lang.org/ja/1.8.7/class/Open3.html

yasuhira1011
質問者

補足

ここのマニュアルは読んでます。 SSHでの接続で、シェルスクリプトを実行するところまでは出来ていて、 実行するシェルスクリプトがRubyからの標準入力を受け取る方法が分かれば解決なのかと思っています。 どうも、根本的にシェルが分かってないので、 なんともかんともって感じです。 厳しい。

関連するQ&A

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

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

    • ベストアンサー
    • Ruby
  • rsyncをrubyのプログラムで使いたい。

    rubyである条件を満たせばrsyncでバックアップするというプログラムを作っています。 if 条件  バックアップ end 上記のような簡単なプログラムな場合のとき if 条件  rsync -a -e ssh バックアップ元 バックアップ先 end というようにrsyncをシェルスクリプトのコマンドのように使うことはできないですよね? ちなみに今作っているプログラムはシェルスクリプトではつくってません。 そうなるとrsyncをするプログラムをif文に書くしかないんですかね? cygwinでrubyをインストールして使っているのですが、パッケージの中にはrsync.rbのようなものがないようなのでやっぱり使えないってことですよね? ちなみに初心者なんでrsyncをするプログラムをつくれるとは思えないです。 なんか簡単な方法はないですか?? ご教授をよろしくお願いします。

  • rubyの構文(&&を用いた条件分岐について)

    ruby初心者です。 最近、ruby on railsで書かれたソースを引き継ぎ解析を行っています。 その中で、以下のような構文が出てきました。 ========================================= num = 0 bool = false vals = '' puts 'start' num == 0 && bool && if vals  puts 'true' else  puts 'false' end puts 'end' ========================================= 上記プログラムを実行すると、if ~ end までが実行されませんでした。 そこで、変数boolをtrueに変更して再実行したところ、if文が実行されました。 そこで私は、上記プログラムは以下と同値であると解釈しました。 ====================================== (省略) if num == 0 && bool  if vals   puts 'true'  else   puts 'false'  end end ======================================= 以上を踏まえて・・・ 1.私の解釈は正しいでしょうか? 2.間違っている場合、正しい処理の解釈を教えていただけますでしょうか?または参考URLを教えていただけますと助かります。 文の最後に"&&"がついている文を見たことがなく、ネットで調べても 正解らしいものが掲載されていなかったので質問させていただきました。 拙い説明で申し訳ありませんが、よろしくお願いいたします。

    • ベストアンサー
    • Ruby
  • ruby forkについて教えて下さい

    親プロで用意した配列の中の要素を一つづつ子プロでputsした後、最後一回、親プロで生成した子プロのPIDを確認したいです。 こんなふうに書いてみました。 #!/usr/bin/ruby table=%w(a b c d) array=[] while i=table.pop do if pid=fork then array.push pid puts pid break if table.size > 0 p array else puts i end end 実行すると、以下のような結果になりました。 $9200 c 9201 b 9202 [9202] a $ PIDが一つしか得られてません。 どうしたらよいでしょうか? ご教授の程、宜しくお願いいたします。 rubyは 1.8.7 を使ってます。 以上、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • rubyのunlessで遊んでいたら

    Rubyのunlessで適当にプログラムをつくって遊んでいました。 01:a = 10 #aに10を代入 02:b = 20 #bに20を代入 03: 04:unless a > b 05: puts "aはbより大きくない" 06:else 07: puts "aはbより小さくない" 08:end 09:#unless文にはelsif節等がなく、条件項目を増やせないのでaとbの値が同じ場合は 10:#どうしようかと、これをif文で補おうとしました。 11:if a = b 12: puts "aとbは同じです" 13:end 14: 15:puts "a=#{a} b=#{b}" そもそも、aとbの値が同じでない場合11行目のifが実行されることは無いだろうと思っていたのですが実効結果は ↓ aはbより大きくない aはbと同じ a=20 b=20 という結果がでました。実行結果一行目の「aはbより大きくない」と出力されたのはプログラム4行目のunless文の返した結果だろうと理解できましたが、実行結果2行目のif文の結果である「aはbとおなじ」が出力されたのか、実行結果3行目でaとbの変数内を参照しておりますが、ここでどうしてaの値が20に変更されているのか、わかりません。 詳しい方いらっしゃいましたらご教授願います。

    • ベストアンサー
    • Ruby
  • 【Ruby初心者】簡単なプログラムが実行しない

    教材でRubyを勉強中なのですが、以下のプログラムが実行されず爆死しています。 --- puts("整数を入力してね") number = gets.to_i if number > 0 then puts("正の数です!”) end --- 文字コードは、UTF-8で指定、OSはMacです。CotEditorを使用しています。 数字/アルファベットだけのプログラムは正常に実行されるのですが、 文字入りのプログラムがうまく実行されません。 プレビュー見ると文字化けしているので(添付画像参照)、 文字入力にバグが起因していると思われますがお手上げ状態です。

    • ベストアンサー
    • Ruby
  • rubyで標準入力とファイルからのgets

    ActiveScriptRuby v1.8.5でやっています。 実行時にコマンドラインでファイル名を与えてファイルの内容を取得した後、氷人出力からも入力をとろうとしています。しかしファイルの内容を読み出したあとのgetsがnilを返すだけで標準入力から入力をとれません。以下のようなコードでやっています。 ##stdin.rb while line = gets do print line break if line.chomp.empty? end puts' - ' print gets #ここで標準入力から文字をとりたい 実行時は ruby stdin.rb moji.txt という感じで読ませたいファイル名を渡しています。 マニュアルには 最後まで ARGF を読み込んだ後、再度 ARGF から内容を読むと (ARGV が空なので)標準入力からの読み込みとなります。 とありますが、どこがおかしいのかさっぱりわかりません。 アドバイスなどよろしくお願いします

  • rubyのプログラム

    プログラミング初心者です。参考書のソースコードをそのままコピペして実行したのですが、エラーが出てしまいます。どこが間違っているのかご指摘いただけると助かります。 ソースコード #encoding: cp932 # うるう年かどうかによって時間数は変わります puts 24*365 puts " (#{24*366}になる場合もある) " 実行結果 >ruby calc.rb calc.rb:4: invalid multibyte char (Windows-31J) calc.rb:4: syntax error, unexpected tIDENTIFIER, expecting $end puts "(#{24*366}になる場合もある)" ^ >Exit code: 1 パソコンOS Windows7 rubyのバージョン 1.92

    • ベストアンサー
    • Ruby
  • _popen() のエラー取得

    WindowsNT/2000で_popen()を利用してコマンドを実行しているのですが、その際のメッセージを取得したいのですが、通常のメッセージは取得出来るのですが、エラーメッセージが取得出来ません。どうすればよいのでしょうか? 現在のソースは下記のようです。 int main(int argc, char* argv[]) { char str[512],*ptr; FILE *fp; if((fp = _popen("dir b:","rt")) == NULL) { fprintf( stderr , "error!!!\n"); return -1; } while(1) { fgets(str,512,fp); if(feof(fp)) { break; } ptr = strchr(str,'\n'); if(ptr != NULL) { *ptr='\0'; } printf("%s\n",str); } _pclose(fp); return 0; }

  • Rubyにおける変数

    Windows2000上で、Rubyを動かしています。 皆様のお陰で、少しずつ進んでおります。しかし、また質問させてください。 変数に、ファイル名を代入して、実行すると、動かなくなりました。 実名を入れた、system('tar zxf test_20070511.tar.gz')では、動きますが、 変数にした、system('tar zxf myFilename')では、動きません。 Rubyスクリプト ---------------------- print Dir.getwd,"\n" Dir.chdir('C:\myData\myData2') print Dir.getwd,"\n" dir = Dir.open('C:\myData\myData2') while myFilename=dir.read do if /.tar.gz/i =~myFilename then puts myFilename system('tar zxf myFilename') end end dir.close ------------------------------------ 宜しくお願いいたします。