Weź stdin z pliku, ale nadal pokaże się w terminalu

9

Mam program, który wymaga ode mnie wprowadzania danych podczas działania programu. Wyobraź sobie coś takiego:

$ ./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
...

Teraz mam wiele wejść testowych do uruchomienia mojego programu. Wszystkie zawierają coś takiego:

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

Jednak niektóre moje skrypty testowe zawodzą i niestety bardzo trudno jest mi rozszyfrować dokładnie to, gdzie zawiodły, ponieważ mój terminal wygląda tak:

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

Czy istnieje sposób, w jaki mogę przekazać dane wejściowe stdinza pomocą pliku, ale nadal wyświetlać terminal tak, jakbym wpisał to wszystko?

Linux Mint 16 to mój system operacyjny, jeśli to ma znaczenie.

Zambezi
źródło
Nie wiem, jak to zrobić, ale „powinieneś” móc to zrobić za pomocą (niebuforowanych) urządzeń tty. Aby uzyskać wskazówki, zobacz stackoverflow.com/questions/8514735/ ...
Joe,

Odpowiedzi:

13

Zamiast używać przekierowania wejściowego (./program <arthur.txt), który tylko buforuje dane wejściowe do programu, powinieneś używać narzędzi tak, jak „oczekujesz”, czekając na pytanie i wysyłając odpowiedzi jedna po drugiej.

#!/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"

Lepsze przykłady: http://www.pantz.org/software/expect/expect_examples_and_tips.html

jakiś użytkownik
źródło
Gdy powyższe działanie zadziała, możesz przekształcić go w expectskrypt, który wie, co powoduje problemy z programem, i umie podać swój trzeci wiersz danych wejściowych w odpowiedzi na „Jaki jest twój ulubiony kolor?”. pytanie - a następnie expectskrypt powinien odczytać arthur.txtplik (lub inny określony plik o odpowiedniej strukturze), aby uzyskać te dane wejściowe, zamiast zapisywać je na stałe w skrypcie.
G-Man mówi „Reinstate Monica”
7

Właśnie do tego teesłuży.

Na przykład:

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

To, co się tutaj dzieje, to tee bierze standardowe wejście i kopiuje je na standardowe wyjście, a następnie ponownie je wyrzuca. Zupełnie jak na styku rur

Sprawdź tee strony podręcznika (1), aby uzyskać więcej informacji.

Dwight Spencer
źródło
1
Czy wiadomości mają być wyświetlane we właściwej kolejności? Nawet ignorując buforowanie, są to zasadniczo dwa programy działające jednocześnie i próbujące pisać na tym samym ekranie.
Federico Poloni
1
Jak jednak wykorzystać to w moim scenariuszu? Próbowałem czytać strony podręcznika, ale wydaje się, że w tym narzędziu jest o wiele więcej niż tylko moja skrzynka i nie do końca rozumiem, jak z niego skorzystam, jeśli chodzi o program.exei arthur.txt.
Zambezi
@Zambezicat arthur.txt | tee >( program.exe )
gronostaj
2
tee było pierwszą rzeczą, jaka przyszła mi do głowy. Ale próbowałem i potwierdziłem, że to nie działa. Dane wyjściowe są wyświetlane osobno. W moim eksperymencie najpierw pojawia się treść arthur.txt, a następnie pytania z programu.exe. Możesz być w stanie sprawić, że będzie działał z „unbuffer”, ale nie miałem szczęścia.
jakiś użytkownik