0

I have a Linux program that gives the user a prompt, takes a one line input from stdin, performs an action, and then returns to the prompt to repeat (unless the action is "exit"). I would like to automate giving an exact sequence of inputs to the program in a way that displays exactly the same as if I had entered it from the keyboard. In other words, to look like this:

prompt> one
prompt> two
prompt> three

My first thought was that I would create a file input.txt with these contents:

one
two
three

And then run the command:

./a.out < input.txt

This gives the right program behavior but the display shows this, instead of being identical to the first code block above:

prompt> prompt> prompt> 

Is there any way I can get the input from a file that will display the inputs (at the correct points) so the display looks like the first code block above?

Important Notes:

  • I can modify the input file however I want, but I cannot modify the program.

  • The output will also be redirected to the file, so solutions that get what I want "displayed" in the file are fine, however they work. (e.g., a hack that puts the input file contents directly into the output file would be fine, but only if the individual inputs end up at the right points relative to the program output, so it looks like the example above)

  • I can use bash script (or Python or C) to implement the solution, if it's more complicated than a single command line (but bash would be preferred, unless it's significantly easier to implement in another language)

Thanks!

Edits: What I have found out about using tee so far...

The man page for tee does say that giving - to tee causes it to copy again to stdout, but that just results in two copies of everything being passed as input to ./a.out. If I run ```tee - < input.txt`` then it prints this:

one
two
three
one
two
three

and if I pipe the output of tee to a.out then all of that becomes input to a.out

So then I tried tee /dev/tty < input.txt which does correctly direct the copy of the stream directly to the terminal while only the original copy gets redirected. So tee /dev/tty < input.txt | ./a.out gives the correct input to a.out and I also see the inputs on the screen, but two problems arise:

1) It seems to dump the entire input at once instead of displaying as it is read from the stdin stream. In other words, the output looks like this:

prompt> one
two
three
prompt> prompt>

2) If I redirect the output of a.out to a file (which is the ultimate goal) then the stream that was sent to /dev/tty is still printed to the terminal and does not appear in the output file. So the command tee /dev/tty < input.txt | ./a.out > output.txt will write this into the output.txt file:

prompt> prompt> prompt> 

and this will still be displayed on the terminal:

one
two
three

(It kinda makes sense if you think about what sending it to /dev/tty actually means...) So one thing I thought about trying was having tee send it directly to the output file, like tee -a output.txt | ./a.out >> output.txt and that does send everything to the output file, so it fixes (2) above but (1) is still a problem and the file contents looks like:

one
two
three
prompt> prompt> prompt> 
0

When you do

./a.out < input.txt

STDIN of your a.out is fed from the input.txt. Normally, the system, not the program, echoes your input, so the one, two and three are not output by your program. Therefore, it is normal that you get the

prompt> prompt> prompt> 

This notion is important if you want to redirect the output with your input.

You could try

cat input.txt | tee /dev/tty | ./a.out

but, due to buffering, it will probably produce out-of-sync prompts and inputs, something like this:

one
two
prompt>
three
prompt> prompt

and the tee output is written to /dev/tty and therefore not redirectable.

An option would be to use expect and something like this:

#!/usr/bin/expect
log_user 0
spawn ./a.out
log_user 1
expect prompt
send "one\r"
expect prompt
send "two\r"
expect prompt
send "three\r"
expect prompt

which produces:

prompt >one
prompt >two
prompt >three

The output from expect is completely redirectable.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.