How can I capture the input text and output text of a process in a file as it will appear when it runs from a shell


I need to test some programs by running them and verifying the output, and the entire test data shall be copied into a report. By entire test data, I mean both the output (stdout) of the program and the input (stdin) to the program need to be in the report. For example, let's say I run python to do some calculations. A simple session may look like this:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> math.sqrt(2)
>>> math.log(2)
>>> 2 ** 32

Here, I have my inputs and the outputs (the prompts and results of my calculations).

My question is, given a program and possibly a file containing the stdin for that program, how can I get all textual data of the program's run as though I ran it interactively, like the above python session? In other words, how can I get the above text from the python session given the python program and a text file (for input) containing:

import math
2 ** 32

I could run the program in a shell and copy the output, but it doesn't seem like a clean, systematic way of doing it. Instead, I'm thinking writing another program that takes the given program as an argument as well as a filename (from which to read input). This second program would read from the given file, fork the given program, forward the text from the file to the given program (by means of a pipe), and read the output of the given program (also by a pipe). That way this intermediary program can read both the input and the output, and can write them to another file.

The only problem I foresee is that due to stream buffers and what not, the placement of the inputs and outputs in the final output file will be off, and I won't get the intended output. So, is my logic correct, and if so, will I be able to get the output the way I want it? Is there a simpler way to do this, e.g., a program already exists that does this?

Sorry for the long explanation. Thanks for your responses.

Try the script command. By default it only captures output, but it can also capture input as well.

script -akq capture.log my-fun-little-command and its args