2016-03-07 166 views
0

Answering a cli prompt in ruby with open3?”是一个可能重复的问题,但它没有答案。模拟命令提示符命令

我需要编写一个程序来编译和执行一个C程序,给出输入并返回输出。到目前为止,我想出了这一点:

对于单输入:

Open3.popen3('one.exe') do |stdin, stdout, stderr| 
    stdin.puts "45\n" 
    STDOUT.puts stdout.gets 
end 

,输出是:

Enter the temperature in degrees fahrenheit: The converted temperature is 7.222222 

对于两个或多个输入:

Open3.popen3('two.exe') do |stdin, stdout, stderr| 
    stdin.puts "45 45" 
# This line works the same as the previous one. 
# stdin.puts "45\r\n45" 
    stdin.close 

    STDOUT.puts stdout.gets 
end 

和输出为:

Enter first number: Enter second number: Sum is 90 

的问题是,我没有回去我放在输入。

有没有一种方法,我可以纠正或者一个更好的方式来做到这一点?

回答

1

考虑一下:

使用创建输入文件:

cat > test.input 
bar 
baz 

然后按CTRL +d终止输入,这将导致文件test.input创建。

在同一目录中这段代码保存为test.rb

2.times do |i| 
    user_input = gets.chomp 
    puts "#{ i }: #{ user_input }" 
end 

使用运行代码:

ruby test.rb < test.input 

,你应该看到:

0: bar 
1: baz 

这部作品的原因是因为gets读取STDIN(默认情况下)查找行结束,在这种情况下是跟随barbaz的字符。如果我在IRB加载输入文件可以很容易地看到文件的内容:

input = File.read('test.input') 
=> "bar\nbaz\n" 

2.times说,读线的两倍,因此它从文件中读取两行并继续,跌出了times循环。

这意味着您可以创建一个文件,将其管理到您的脚本中,Ruby将做正确的事情。我可以重写测试。RB代码:

puts `sh ./test.sh < #{ ARGV[0] }` 

,并创建test.sh

for i in 1 2 
do 
    read line 
    echo $i $line 
done 

然后使用叫它:

ruby test.rb test.input 

,并得到:

1 bar 
2 baz 

由于反引号很多之一方法来称呼她或者运行代码,您可以调整调用代码和/或孩子,以读取文件。或者让Ruby读取输入并生成要调用的文件。或者使用Expect进行调查,但我不会希望对任何人。

这应该有助于你走上正确的道路。

+0

感谢您的回复。我尝试了上面的例子,它们按预期工作,所以我跳回到我原来的任务,** temp.rb **的内容:'puts%x [sh ./test.sh