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 the comp.lang.tcl newsgroup:
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 a simple example, maybe useful for newbies (like myself, GV). This reads multimple rows from the standard input (stdin) and keep al the lines into 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