Piping an interactive session to a file
Asked Answered
P

4

14

I have made a toy interactive console program that is basically an interpreter:

$ myprogram
> this is user input
this is program output

I want to pipe the full session, both user input and program output, into a log file. I can do this like so:

$ cat | tee >(myprogram | tee -a file.log) >> file.log
> this is user input
this is program output
$ cat file.log
> this is user input
this is program output

So the above session will display to the terminal as usual but will also be duplicated to the log file.

Is there a better way to do this? I don't like how I have to write the log file twice, nor how I have to remember to wipe it before running this command.

Pruinose answered 15/9, 2013 at 11:56 Comment(1)
Tee command is meant for redirecting the output to file.Basically it copies your output to file if you write $output | tee file.log it will copy output to file.logParfait
S
6

The simpler form could be

tee >(myprogram) | tee -a file.log

If you want to prevent input being shown again to the screen:

tee -a file.log | myprogram | tee -a file.log
Snort answered 15/9, 2013 at 13:3 Comment(1)
Thanks, I didn't realize tee would default to reading from stdin, making the call to cat redundant. It's a shame I have to write file.log twice but not the end of the world.Pruinose
S
14

script — make typescript of terminal session:

script -c "myprogram" file.log

The whole session will be logged to file.log

Sse answered 25/11, 2013 at 8:26 Comment(3)
This works, but it captures all characters (including escape sequences), which may make the log file tough to readSarette
and after that, you can use the file.log in ansifilter (gitlab.com/saalen/ansifilter) or highlight (gitlab.com/saalen/highlight) to reprocess it 👌Ayeshaayin
It also does some weird stuttering by default, even with echo off. For example, typing print "HI" in IRB gives: irb(main):001:0> irb(main):001:0> pirb(main):001:0> prirb(main):001:0> priirb(main):001:0> prinirb(main):001:0> printirb(main):001:0> print irb(main):001:0> ...Alaniz
S
7

As two processes can't read the same input two tees are needed, one which reads terminal input and writes to program standard input and file.log another which reads program standard output and writes into terminal output and file.log:

tee -a file.log | program | tee -a file.log
Sepia answered 15/9, 2013 at 13:5 Comment(1)
Thanks. I gave the answer to konsolebox because he beat you by about 3 minutes but the explanation helps make me feel better about using tee twice.Pruinose
S
6

The simpler form could be

tee >(myprogram) | tee -a file.log

If you want to prevent input being shown again to the screen:

tee -a file.log | myprogram | tee -a file.log
Snort answered 15/9, 2013 at 13:3 Comment(1)
Thanks, I didn't realize tee would default to reading from stdin, making the call to cat redundant. It's a shame I have to write file.log twice but not the end of the world.Pruinose
H
2

An easy way is to use the script command. It just stores your whole terminal session. Run it with:

script my-interactive-session.log program
Hydrazine answered 10/11, 2013 at 23:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.