Prenez stdin du fichier mais faites-le toujours apparaître dans le terminal

9

J'ai un programme qui m'oblige à saisir des données pendant l'exécution du programme. Imaginez quelque chose comme ça:

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

Maintenant, j'ai un certain nombre d'entrées de test pour exécuter mon programme. Ils contiennent tous quelque chose comme:

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

Cependant, certains de mes scripts de test échouent, et malheureusement, il m'est très difficile de déchiffrer exactement où ils ont échoué, car mon terminal ressemble à ceci:

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

Existe-t-il un moyen de donner une entrée stdinvia un fichier, tout en laissant le terminal apparaître comme si j'avais tout tapé?

Linux Mint 16 est mon système d'exploitation si cela importe.

Zambezi
la source
Je ne sais pas comment faire cela, mais vous "devriez" pouvoir le faire en utilisant des périphériques tty (sans tampon). Voir stackoverflow.com/questions/8514735/… pour quelques indices.
Joe

Réponses:

13

Au lieu d'utiliser la redirection d'entrée (./program <arthur.txt), qui ne fait que mettre en mémoire tampon les entrées de votre programme, vous devez utiliser des outils tout comme "attendre" pour attendre la question et envoyer les réponses une par une.

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

De meilleurs exemples: http://www.pantz.org/software/expect/expect_examples_and_tips.html

un utilisateur
la source
Une fois que vous avez obtenu ce qui précède, vous pouvez le transformer en un expectscript qui sait ce qui provoque les problèmes de votre programme et sait alimenter votre programme la troisième ligne d'entrée en réponse à la "Quelle est votre couleur préférée?" question - puis demandez au expectscript de lire le arthur.txtfichier (ou tout autre fichier spécifié, correctement structuré) pour obtenir ces entrées, plutôt que de les avoir codées en dur dans le script.
G-Man dit `` Réintègre Monica '' le
7

C'est exactement ce à quoi teesert.

Par exemple:

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

Ce qui se passe ici, c'est que tee prend stdin et le copie dans stdout et le rediffuse. Tout comme au joint pour tuyaux.

Consultez le tee-shirt de la page de manuel (1) pour plus de détails.

Dwight Spencer
la source
1
Les messages sont-ils garantis pour apparaître dans le bon ordre, cependant? Même en ignorant la mise en mémoire tampon, il s'agit essentiellement de deux programmes exécutés simultanément et essayant d'écrire sur le même écran.
Federico Poloni
1
Comment utilise-t-on cela dans mon scénario? J'ai essayé de lire les pages de manuel, mais il semble y avoir beaucoup plus à cet outil que mon cas d'utilisation, et je ne comprenais pas vraiment comment je l'utiliserais en ce qui concerne program.exeet arthur.txt.
Zambezi
@Zambezicat arthur.txt | tee >( program.exe )
gronostaj
2
Ce fut aussi la première chose qui me vint à l'esprit. Mais je l'ai essayé et confirmé que cela ne fonctionne pas. La sortie s'affiche séparément. Dans mon expérience, le contenu de arthur.txt apparaît en premier, suivi des questions de program.exe. Vous pourriez être en mesure de le faire fonctionner avec "unbuffer" d'attendre mais je n'ai pas eu de chance.
un utilisateur