Pegue o stdin do arquivo, mas ele ainda aparece no terminal


9

Eu tenho um programa que exige que eu insira dados enquanto o programa é executado. Imagine algo assim:

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

Agora, tenho várias entradas de teste para executar meu programa. Todos eles contêm algo como:

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

No entanto, alguns dos meus scripts de teste falham e, infelizmente, é muito difícil para mim decifrar exatamente onde eles falharam, pois meu terminal se parece com isso:

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

Existe uma maneira que eu ainda possa dar entrada stdinatravés de um arquivo, mas ainda assim o terminal apareça como se eu tivesse digitado tudo?

Linux Mint 16 é o meu sistema operacional, se isso importa.


Não sei como fazer isso, mas você "deveria" conseguir fazer isso usando dispositivos tty (sem buffer). Consulte stackoverflow.com/questions/8514735/… para obter algumas dicas.
— Joe

Respostas:


13

Em vez de usar o redirecionamento de entrada (./program <arthur.txt), que está apenas armazenando um buffer no seu programa, você deve usar ferramentas como "esperar" para aguardar a pergunta e enviar as respostas uma a uma.

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

Melhores exemplos: http://www.pantz.org/software/expect/expect_examples_and_tips.html


Depois de fazer o trabalho acima, você poderá transformá-lo em um expectscript que saiba o que causa problemas no seu programa e saiba que ele alimenta a terceira linha de entrada em resposta ao "Qual é a sua cor favorita?" pergunta - e faça com que o expectscript leia o arthur.txtarquivo (ou qualquer outro arquivo especificado, adequadamente estruturado) para obter essas entradas, em vez de tê-las codificadas no script.
— G-Man diz 'Reinstate Monica'

7

É exatamente para isso que teeé usado.

Por exemplo:

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

O que acontece aqui é que o tee pega o stdin e o copia para o stdout e o envia novamente. Assim como na junta para tubos.

Verifique o tee da página de manual (1) para obter mais detalhes.


11
As mensagens são garantidas para aparecer na ordem correta, no entanto? Mesmo ignorando o buffer, são essencialmente dois programas sendo executados simultaneamente e tentando gravar na mesma tela.
— Federico Poloni

11
Como alguém usa isso no meu cenário? Tentei ler as páginas de manual, mas parece haver muito mais nessa ferramenta do que apenas meu caso de uso, e eu não estava conseguindo entender como usá-la quando se trata program.exee arthur.txt.
— Zambeze

@Zambezicat arthur.txt | tee >( program.exe )
— gronostaj

2
tee foi a primeira coisa que me veio à cabeça também. Mas eu tentei e confirmei que não funciona. A saída aparece separadamente. No meu experimento, o conteúdo do arthur.txt aparece primeiro, seguido pelas perguntas do program.exe. Você pode conseguir que ele funcione com um "buffer" de expectativa, mas não tive sorte.
— algum usuário
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.