Richard Suchenwirth 2007-02-15 - A colleague wanted a way to capture stdout of a Tcl process temporarily redirected into a variable. Here's my solution, another puts workaround done by briefly overloading puts, and restoring it afterwards:
proc getputs body { variable putsbuffer "" if {[info commands puts_] eq ""} { rename puts puts_ } proc puts args { set str [lindex $args end] set arg1 [lindex $args 0] set nonew [string equal $arg1 -nonewline] switch -glob [llength $args],$nonew { 1,* {set chan stdout; append str \n} 2,0 {set chan $arg1; append str \n} 2,1 {set chan stdout} 3,1 {set chan [lindex $args 1]} default { error {wrong \# args: should be "puts ?-nonewline? ?channelId? string"} } } if {$chan ne "stdout"} { puts_ -nonewline $chan $str } else {append ::putsbuffer $str} return } set code [catch {uplevel 1 $body} res] if {$code} {append putsbuffer $code:$res} rename puts {} rename puts_ puts return -code $code $putsbuffer } #--- Testing: puts before set var [getputs { puts -nonewline hello, puts world puts stdout inside! puts stderr stderr... #expr 1/0 }] puts after:[string toupper $var]
which shows on stdout:
before stderr... after:HELLO,WORLD INSIDE!