Answering a cli prompt in ruby with open3?

2019-06-14 19:02发布

Apologies for lack of sample code, I'm on mobile at the moment.

I've gotten ruby+open3 to run commands and save stdout and stderr to a variable.

My question is, if the command line interface prompts the user is it possible to input text into the prompt and press enter? If so how would I go about doing this.

Example explanation Runs program, program in terminal then asks "what is your name?" and waits for input.

I want to input a name, press enter.

Then it asks next question, I want to put to stdin and answer that as well

This is for an automation test. If anyone has a better idea than open3 I'm all ears but I'm restricted to ruby

Thanks

1条回答
霸刀☆藐视天下
2楼-- · 2019-06-14 19:45

Consider this:

Create an input file using:

cat > test.input
bar
baz

Then press CTRL+D to terminate the input, which will cause the file test.input to be created.

In the same directory save this code as test.rb:

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

Run the code using:

ruby test.rb < test.input

and you should see:

0: bar
1: baz

The reason this works is because gets reads the STDIN (by default) looking for a line-end, which in this case is the character trailing bar and baz. If I load the input file in IRB it's easy to see the content of the file:

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

2.times says to read a line twice, so it reads both lines from the file and continues, falling out of the times loop.

This means you can create a file, pipe it into your script, and Ruby will do the right thing. If Ruby has called a sub-shell, the sub-shell will inherit Ruby's STDIN, STDOUT and STDERR streams. I can rewrite the test.rb code to:

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

and create test.sh:

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

then call it using:

ruby test.rb test.input

and get:

1 bar
2 baz
查看更多
登录 后发表回答