When you start tclsh or wish (on Unix and perhaps a few other platforms) without a filename, you will get a prompt so you can interact with Tcl. (For wish on Windows, use console show instead). If you start them with a filename, that script is executed, but the interactive prompt does not appear.
What if you want both? Donald Porter presented this solution on comp.lang.tcl:
set cmd "" while 1 { if { "$cmd" != "" } { # Why "format catch"? It "is a legacy workaround # for an old bytcode compiler bug." We should # find out when it's fixed, and "package require # Tcl ..." appropriately. catch {[format catch] $::tcl_prompt2} } else { if {[catch {[format catch] $::tcl_prompt1}]} { puts -nonewline "% " } } flush stdout append cmd \n[gets stdin] if [ info complete $cmd ] { catch $cmd res puts $res set cmd "" } }
Other improvements that could still be made:
Note that the code above is best understood as an improvement on the implementation developed in this Usenet thread: http://groups.google.com/groups?hl=en&th=79c056a40deb476d&rnum=4
Given the original problem description, the right solution in wish is [console show]. With a little hacking you can have a console for Unix, or better yet, make use of TkCon [L1 ].
For tclsh only, no console widget is available, so then I would go ahead and use [vwait forever] to get an event loop going and use [fileevent stdin readable] to collect and evaluate interactive commands from stdin rather than the [while] loop above.
DGP
There is similar code at Integrating Tcl and Emacs on Windows for a more specific purpose.
Simple example: from stdio to variable
Instead, this is simple example may be useful for newbies (like myself, GV). This reads multiple lines from the standard input (stdin) and keeps all the lines in a variable. Last input line must be a dot (".").
set n 0 while {$n<3000} { gets stdin row puts $row if { [string equal $row "."] } { break }; append message $row "\n" } puts "---------" puts $message