** Summary ** A small beginner-level example of using [Expect] to feed a script to [tclsh] ** The Sequential Version ** This script reads a Tcl script and enters it into an interactive [tclsh]. ====== #! /bin/env tclsh package require Expect proc tclprompt {} { proc [lindex [info level 0] 0] {} { return {\n%\s$} } return {%\s*$} } set timeout -1 set fh [open [lindex $argv 0]] set script [split [read $fh][close $fh] \n] spawn tclsh set command {} foreach line $script { if {[set line [string trimright $line]] eq {}} { continue } else { append command $line\r } if {[info complete $command]} { expect -re [tclprompt] { send $command set command {} } } } expect -re [tclprompt] ====== Some interesting points: Setting timeout to -1 allows expect to wait as long as necessary for the next prompt. [[tclprompt] uses a `$` to anchor the prompt to the end of the output. Expect is not line-oriented, so this is not foolproof. [[tclprompt] is implemented as a command rather than a variable because the first prompt is not preceded by a newline character, but subsequent prompts are, and manipulating the proc one time is more succinct than putting an extra conditional into the [foreach] statement. simply checking for "%" is less robust than checking for a newline followed by "%" followed by space followed by the end of output. It's generally a good idea to be as specific as possible when expecting a prompt. ** The Event-Driven Version ** Here is an event-driven version of the same thing (only tested on *nix): ====== #! /bin/env tclsh package require Expect proc input {fh {command {}}} { if {$command ne {} && [info complete $command]} { send $command after 0 [list prompt $fh] return } if {[eof $fh]} { set ::done 1 return } gets $fh line if {[set line [string trimright $line]] ne {}} { append command $line\r } after 0 [list input $fh $command] } proc prompt {fh} { expect -re [tclprompt] { after 0 [list input $fh] } } proc tclprompt {} { proc [lindex [info level 0] 0] {} { return {\n%\s$} } return {%\s*$} } spawn tclsh set timeout -1 set fh [open [lindex $argv 0]] after 0 prompt $fh vwait done ====== <> Expect