質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Q&A

解決済

1回答

2348閲覧

標準入出力を組み合わせて取得する方法

Neight

総合スコア127

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

0グッド

0クリップ

投稿2016/12/21 16:04

編集2016/12/22 07:34

標準入出力の取得方法について教えてください。

例えば下記のようなコードがあったとします。

C++

1// foo.cpp 2#include <iostream> 3using namespace std; 4 5int main(void) 6{ 7 int num; 8 9 cout << "input num:"; 10 cin >> num; 11 12 cout << "output num:" << num << endl; 13 14 return 0; 15}

これをコンパイルした後にしコマンドライン実行するために以下のようなスクリプトを作成しました。

Ruby

1# test.rb 2require 'oepn3' 3 4Open3.popen3("./a.out") do |i, o, e, w| 5 i.puts(10) 6 i.close 7 o.each do |line| p line end 8 e.each do |line| p line end 9end

この時出力できるログは次の用になります。

$ ruby test.rb input num:output num:10 $

このときに標準出力内に入力が含まれたログを取りたいと考えています。
どの様にすればよいでしょうか?


追記

otnさんの回答を基に次のようなスクリプトを作成しました。

Ruby

1require 'open3' 2 3data=10 4Open3.popen3("./a.out") do |i, o, e, w| 5 begin 6 # puts "ouput:" 7 print o.read_nonblock(100) 8 rescue IO::WaitReadable 9 # puts "IO::WaitReadable" 10 sleep(0.01) 11 retry 12 rescue 13 # puts "rescue:" 14 i.puts(data) 15 puts data 16 end 17 18 i.close 19 20 o.each do |line| puts line end 21 e.each do |line| puts line end 22end

これでおおよ上手く動作したのですが、1つ懸念事項があります。
質問内で使用したC++のプログラムを次のように改変した場合にIO::WaitReadableのエラーが吐かれ続けてしまい、無限ループになってしまうという問題です。

C++

1#include <iostream> 2using namespace std; 3 4int main(void) 5{ 6 int num; 7 8 // 初期出力をなくした場合 9 // cout << "input num:"; 10 cin >> num; 11 12 cout << "output num:" << num << endl; 13 14 return 0; 15}

何故このような自体になってしまうかがよく分かりません。
何方かお教えいただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

標準入力に与えたものと標準出力から受け取った物を時系列に並べるというのは、汎用の物を書くのは面倒だと思います。
この対象プログラムの場合だと、

Ruby

1require 'open3' 2 3data="10" 4Open3.popen3("./a.out") do |i, o, e, w| 5 print o.readpartial(100) 6 i.puts(data) 7 puts data 8 i.close 9 o.each do |line| print line end 10 e.each do |line| print line end 11end

投稿2016/12/22 01:33

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Neight

2016/12/22 07:36

ありがとうございます。 添付していただいたソースコードを基に色々と改良してみた所、read_notblockというメソッドを利用するのが良さそうだという結論にたどり着きました。 ただし、質問に補足した懸念事項が発生したためもしよろしければそちらもお教えいただけると幸いです。
otn

2016/12/22 07:44

> 質問内で使用したC++のプログラムを次のように改変した場合にIO::WaitReadableのエラーが吐かれ続けてしまい、無限ループになってしまうという問題です。 そりゃ、i.puts(data) しないとプログラムは出力を出さないのに、それを読もうとトライし続けるからですね。 readせずにputsから入ってください。 対象プログラムとどういう順序でやりとりするのかを意識したプログラムにする必要があります。
Neight

2016/12/22 08:08

IO:WaitReadableはIOの出力が受け取れる状態にないというエラーではないんですね。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問