“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
问题是,我没有收到我输入的输入。
有没有办法可以纠正它,或者更好的方法呢?
答案 0 :(得分: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(默认情况下)查找行尾,在这种情况下是尾随bar
和baz
的字符。如果我在IRB中加载输入文件,则很容易看到文件的内容:
input = File.read('test.input')
=> "bar\nbaz\n"
2.times
说读两行,所以它从文件中读取两行并继续,从times
循环中删除。
这意味着您可以创建一个文件,将其传递到您的脚本中,Ruby将做正确的事情。我可以将test.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
由于反引号是调用子shell或运行代码的众多方法之一,因此您可以调整调用代码和/或子代,以读取文件。或者让Ruby读取输入并生成要调用的文件。或使用期望进行调查,但我不希望任何人使用。
这应该有助于你走上正确的道路。