Возьмите stdin из файла, но все равно покажите его в терминале

9

У меня есть программа, которая требует от меня ввода данных во время работы программы. Представь себе что-то вроде этого:

$ ./program
Hi there. What's your name? Zambezi
What is your quest? To make a program which runs nicely
What is your favourite color? Red
...

Теперь у меня есть несколько тестовых входов, с которыми я могу столкнуться. Все они содержат что-то вроде:

Arthur, King of the Britons
To seek the Holy Grail
...

Однако некоторые из моих тестовых сценариев терпят неудачу, и, к сожалению, мне очень трудно расшифровать, где именно они произошли, поскольку мой терминал выглядит так:

$ ./program < arthur.txt
Hi there. What's your name?What is your quest?What is your favourite color?...

Есть ли способ, которым я все еще могу дать ввод stdinчерез файл, но при этом все равно появляется терминал, как будто я все это набрал?

Linux Mint 16 - это моя ОС, если это имеет значение.

Zambezi
источник
Я не знаю, как это сделать, но вы «должны» быть в состоянии сделать это, используя (небуферизованные) tty устройства. См. Stackoverflow.com/questions/8514735/… для некоторых подсказок.
Джо

Ответы:

13

Вместо использования перенаправления ввода (./program <arthur.txt), которое просто буферизует ввод в вашу программу, вы должны использовать инструменты так же, как «ожидайте», чтобы дождаться вопроса и отправлять ответы по одному.

#!/usr/bin/expect
log_user 0
spawn ./program
log_user 1

expect {
  "*?"
}
send "Arthur, King of the Britons\r"

expect {
  "*?"
}
send "To seek the Holy Grail\r"

expect {
  "*?"
}
send "...\r"

Лучшие примеры: http://www.pantz.org/software/expect/expect_examples_and_tips.html

какой-то пользователь
источник
После того, как вышеперечисленное сработало, вы могли бы превратить его в expectскрипт, который знает, что вызывает вашу программу, и знает, чтобы передать вашей программе третью строку ввода в ответ на вопрос «Какой ваш любимый цвет?» вопрос - а затем попросите expectсценарий прочитать arthur.txtфайл (или любой другой указанный, надлежащим образом структурированный файл), чтобы получить эти входные данные, а не жестко запрограммировать их в сценарии.
G-Man говорит: «Восстановите Монику»
7

Это именно то, что teeиспользуется для.

Например:

$  echo foo | tee >( grep bar ) 
foo
$

То, что происходит здесь, - это то, что тройник берет stdin и копирует его в stdout и снова выводит его. Прямо как на стыке труб.

Проверьте man-tee (1) для более подробной информации.

Дуайт Спенсер
источник
1
Сообщения гарантированно отображаются в правильном порядке? Даже игнорируя буферизацию, это по сути две программы, работающие одновременно и пытающиеся записать на один экран.
Федерико Полони
1
Как можно использовать это в моем сценарии, хотя? Я пытался читать страницы руководства, но там , кажется, намного больше к этому инструменту , чем просто мое USECASE, и я не совсем получаю , как я хотел бы использовать его , когда дело доходит до program.exeи arthur.txt.
Замбези
@Zambezicat arthur.txt | tee >( program.exe )
gronostaj
2
Это было первое, что пришло мне в голову. Но я попробовал и подтвердил, что это не работает. Выход отображается отдельно. В моем эксперименте сначала показывается содержимое arthur.txt, а затем вопросы из program.exe. Возможно, вы сможете заставить его работать с «небуфером» ожидания, но мне не повезло.
какой-то пользователь