模拟命令提示符命令

时间:2016-03-07 20:13:35

标签: ruby command popen3

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 个答案:

答案 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(默认情况下)查找行尾,在这种情况下是尾随barbaz的字符。如果我在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读取输入并生成要调用的文件。或使用期望进行调查,但我不希望任何人使用。

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