Имитация команд командной строки
" Ответить на приглашение cli в ruby с помощью 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 (по умолчанию), ища конец строки, который в этом случае является завершающим символом 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
Поскольку обратные пометки являются одним из многих способов вызова вложенной оболочки или выполнения кода, вы можете настроить вызывающий код и / или дочерний элемент для чтения файла. Или пусть Ruby прочитает ввод и сгенерирует файл для вызова. Или исследуйте, используя Expect, но я не буду желать этого никому.
Это должно помочь вам встать на правильный путь.