Example—Timing All Commands

In Chapter 7 (p. 176), I showed how to emulate the UNIX script command which records all input and output in an interactive session. Suppose you want a record of just the lines input by the user along with a timestamp showing when each was entered. That can be done with the following script called timeallcmds. It is split into two parts: initialization and a loop. Here is the initialization:

log_user 0
spawn $env(SHELL)
stty raw -echo
set timeout −1
set fp [open typescript w]

Logging is turned off and the terminal is put into no-echo mode. This allows the script complete control over all output that the user sees. The terminal is put into raw mode. The timeout is disabled. Finally, a log file is created. It is called typescript just as in the UNIX script command.

Once the initialization is complete, the script loops executing an expect command repeatedly. The expect command waits for characters from either the user or the process. Characters from the process get sent to the user so that they can be immediately seen. Characters from the user are logged and sent on to the process.

expect {
    -re ".+" {
        send −i $user_spawn_id $expect_out(buffer)
        exp_continue
    }
    eof exit
    −i $user_spawn_id -re "(.*)\r" {
        send −i $spawn_id $expect_out(buffer)
        puts $fp $expect_out(1,string)
        puts $fp [exec date]
        exp_continue
    }
    -re ".+" {
        send −i $spawn_id $expect_out(buffer)
        puts -nonewline $fp $expect_out(buffer)
        exp_continue
    }
}

Two patterns are used to wait for characters from the ...

Get Exploring Expect now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.