Howdy folks!
I got a request from a prof this morning that stumped this old UNIX hack. He wants to run a UNIX command (for a language interpreter), using input from a file, and saving a transcript of the output. That much is trivial. The catch is that he'd like the transcript to have the input echoed, as if it had been typed in at the tty.
I've looked at options on the script command and ssh, but can't find a simple solution to this. And it has to be simple enough for his students (who may not have much UNIX experience) to use.
Any suggestions?
I think the TCL expect package might do the trick. It simulates a person entering text in a terminal session. The command and output are intermix as you want.
On 25/11/11 13:56, Gilbert E. Detillieux wrote:
Howdy folks!
I got a request from a prof this morning that stumped this old UNIX hack. He wants to run a UNIX command (for a language interpreter), using input from a file, and saving a transcript of the output. That much is trivial. The catch is that he'd like the transcript to have the input echoed, as if it had been typed in at the tty.
I've looked at options on the script command and ssh, but can't find a simple solution to this. And it has to be simple enough for his students (who may not have much UNIX experience) to use.
Any suggestions?
On 2011-11-25 14:07, Bill Reid wrote:
I think the TCL expect package might do the trick. It simulates a person entering text in a terminal session. The command and output are intermix as you want.
I though about "expect", but figured that it might be a bit too low-level, and more complicated, than what I'm looking for. This has to be easy enough for novice UNIX users to use. (It's essentially to run a test suite on their programs, written in Prolog. Yikes!)
I'm also not very familiar with actually coding for "expect" (though I've tweaked other people's expect scripts, and at least know a bit about how to use it), and the prof is not at all familiar with it.
Would it be easy to write an expect script to do what I want? (I.e. feed the input from a file, line-by-line, to a program, and collect all the output, including tty echo, into a file?)
Gilbert
On 25/11/11 13:56, Gilbert E. Detillieux wrote:
Howdy folks!
I got a request from a prof this morning that stumped this old UNIX hack. He wants to run a UNIX command (for a language interpreter), using input from a file, and saving a transcript of the output. That much is trivial. The catch is that he'd like the transcript to have the input echoed, as if it had been typed in at the tty.
I've looked at options on the script command and ssh, but can't find a simple solution to this. And it has to be simple enough for his students (who may not have much UNIX experience) to use.
Any suggestions?
Hi Gilbert,
I used expect a lot but it was a decade ago. The problem of synchronizing the input with the output is tough because of buffering. Also I expect the prof does not want the input/output just merged but the input be highlighted in some way so that the student can quickly identify it.
I was using expect to make decisions based on the output of the program which does get complicated.
I checked for expect samples and they really do not do what you want.
-- Bill
On 25/11/11 14:16, Gilbert E. Detillieux wrote:
On 2011-11-25 14:07, Bill Reid wrote:
I think the TCL expect package might do the trick. It simulates a person entering text in a terminal session. The command and output are intermix as you want.
I though about "expect", but figured that it might be a bit too low-level, and more complicated, than what I'm looking for. This has to be easy enough for novice UNIX users to use. (It's essentially to run a test suite on their programs, written in Prolog. Yikes!)
I'm also not very familiar with actually coding for "expect" (though I've tweaked other people's expect scripts, and at least know a bit about how to use it), and the prof is not at all familiar with it.
Would it be easy to write an expect script to do what I want? (I.e. feed the input from a file, line-by-line, to a program, and collect all the output, including tty echo, into a file?)
Gilbert
On 25/11/11 13:56, Gilbert E. Detillieux wrote:
Howdy folks!
I got a request from a prof this morning that stumped this old UNIX hack. He wants to run a UNIX command (for a language interpreter), using input from a file, and saving a transcript of the output. That much is trivial. The catch is that he'd like the transcript to have the input echoed, as if it had been typed in at the tty.
I've looked at options on the script command and ssh, but can't find a simple solution to this. And it has to be simple enough for his students (who may not have much UNIX experience) to use.
Any suggestions?
-----Original Message----- From: roundtable-bounces@muug.mb.ca [mailto:roundtable- bounces@muug.mb.ca] On Behalf Of Gilbert E. Detillieux Sent: Friday, November 25, 2011 1:57 PM To: MUUG Roundtable Subject: [RndTbl] UNIX command transcript with canned input, echoed in output?
Howdy folks!
I got a request from a prof this morning that stumped this old UNIX hack. He wants to run a UNIX command (for a language interpreter), using input from a file, and saving a transcript of the output. That much is trivial. The catch is that he'd like the transcript to have the input echoed, as if it had been typed in at the tty.
I've looked at options on the script command and ssh, but can't find a simple solution to this. And it has to be simple enough for his students (who may not have much UNIX experience) to use.
Any suggestions?
Seems like a strange thing to ask for - how would you discriminate between input and output, since they'd likely be interleaved?
Anyway, the best I can suggest is:
tee copy-of-input < inputfile | interpreter 2>&1 | tee copy-of-output
which would leave you with two files. Of course, this could be wrapped in a trivial function like:
run_script() { DATE=$( date +%F_%T.%N ) cat ${1:-} | tee "input-${DATE}" | interpreter 2>&1 | tee "output-${DATE}" }
in order to make it more easily accessible for novices. Obviously this wouldn't work terribly well for interactive use due to buffering issues; if there were a --line-buffered option for tee(1) this could be workable but no such option exists in GNU tee.
-Adam
On 2011-11-25 14:55, Adam Thompson wrote:
Seems like a strange thing to ask for - how would you discriminate between input and output, since they'd likely be interleaved?
Actually, the whole point is to have the echoed input interleaved with the output, i.e. inserted where it belongs in the sequence.
Since the Prolog interpreter issues a prompt, this would make it fairly easy to distinguish input from output in the transcript, without the need for highlighting.
Anyway, the best I can suggest is:
tee copy-of-input< inputfile | interpreter 2>&1 | tee copy-of-output
which would leave you with two files. Of course, this could be wrapped in a trivial function like:
run_script() { DATE=$( date +%F_%T.%N ) cat ${1:-} | tee "input-${DATE}" | interpreter 2>&1 | tee "output-${DATE}" }
in order to make it more easily accessible for novices. Obviously this wouldn't work terribly well for interactive use due to buffering issues; if there were a --line-buffered option for tee(1) this could be workable but no such option exists in GNU tee.
No, separate files don't help, since the input is already available in a file. The idea is exactly to interleave it. Buffering issues might be a problem too... This is why the solution would likely involve the use of pseudo ttys. (Bill's suggestion of using "expect" is probably close, but more involved than what I'd like.)
On 11/25/2011 03:26 PM, Gilbert E. Detillieux wrote:
On 2011-11-25 14:55, Adam Thompson wrote:
Seems like a strange thing to ask for - how would you discriminate between input and output, since they'd likely be interleaved?
Actually, the whole point is to have the echoed input interleaved with the output, i.e. inserted where it belongs in the sequence.
Since the Prolog interpreter issues a prompt, this would make it fairly easy to distinguish input from output in the transcript, without the need for highlighting.
I don't see a way to do this with the standard tools either.
This is a very slightly modified script from the python pty example at: http://docs.python.org/py3k/library/pty.html
Modifications: Accept `-c command' to set the executable. Also copy stdin to the output if input is not a tty.
So use it just like script(1) but stdin can be a file, and will be copied to the output file. Just like script, it will keep going until the spawned process quits.
Peter
To synchronize the merging of input and output the controlling routine must wait for the prompt before sending the next line of input. This is exactly what expect is prepared to do.
-- Bill
I'm with bill on this one.
Making expect scripts is not very difficult. It is what I used when I took non-imperative for just this purpose though with clisp and prolog interpreters. Oreilly has a good book on it 'exploring expect' (i have a copy) which you are welcome to Gilbert.
On 11/25/2011 09:22 PM, Sean Cody wrote:
Making expect scripts is not very difficult. It is what I used when I took non-imperative for just this purpose though with clisp and prolog interpreters.
The python script worked but didn't need any stupid modifications.
Unfortunately stdin appeared at the beginning of the output in one chunk, and again each time the interpreter read from stdin, because, of course, it doesn't wait for the prompt.
expect is easy enough, though not as easy as cut & pasting a script from python's doc site, and then not testing it at all :-)
Peter