Here is a script that provides a prompt for non-interactive tcl/tk sessions. It uses a fileevent on stdin so as not to block the event loop.
# ==================================================================== # # # prompt.tcl -- # An interactive prompt for non-interactive tcl/tk sessions # Copyright (C) 2000-2010, b i n a r i s m . c o m # # See the file "LICENSE.txt" or "LICENSE.html" for information on usage # and distribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id$ # $Name$ # # ==================================================================== # namespace eval prompt {} # ==================================================================== # proc prompt::_init {} { variable buffer "" variable continue 0 variable prompt1 "% " variable prompt2 "" return } # ==================================================================== # proc prompt::_getline {line} { variable buffer variable continue set n1 [string length $line] set line2 [string trimright $line \\] set n2 [string length $line2] set cont [expr {($n1 - $n2) % 2 == 1}] if { $cont } { set line [string range $line 0 end-1] } if { $continue } { append buffer " [string trimleft $line]" } elseif { [string length $buffer] } { append buffer \n$line } else { set buffer $line } set continue $cont if { $continue } { set complete 0 } else { set complete [info complete $buffer] } if { !$continue && [info complete $buffer] } { set code [catch {uplevel #0 $buffer} result] set std [expr {$code > 0 ? "stderr" : "stdout"}] if { [string length $result] } { puts $std "$result" } set buffer "" _prompt 1 } else { _prompt 2 } return } # ==================================================================== # proc prompt::_readable {chan} { variable status set code [catch {gets $chan line} chars] if { $code > 0 } { puts stderr "error reading $chan: $chars" set status "error" } elseif { $chars > -1 } { _getline $line } elseif { [eof $chan] } { set status "eof" } elseif { [fblocked $chan] } { return } else { set status "unknown" } return } # ==================================================================== # proc prompt::_prompt {n} { global tcl_prompt$n variable prompt$n if { [info exists tcl_prompt$n] } { if { [catch {uplevel #0 [set tcl_prompt$n]} result] } { puts stderr $result flush stderr } } else { puts -nonewline stdout [set prompt$n] } flush stdout return } # ==================================================================== # proc prompt::prompt {} { _prompt 1 fileevent stdin readable [list [namespace current]::_readable stdin] vwait [namespace current]::status return } # ==================================================================== # prompt::_init if { [info exists argv0] && [string equal $argv0 [info script]] } { # set tcl_prompt2 {puts -nonewline "> "} set prompt::prompt2 "> " prompt::prompt } # ==================================================================== #
Example usage:
1. Create a file called hello.tcl containing:
button .b -text "Hello World" -command [list puts "Hello World"] pack .b source prompt.tcl prompt::prompt
1. Run wish with the file:
> wish hello.tcl
and you should be greeted with a prompt.
See also:
* MHo: This only works on unix, actually.