a way to 'pipe' from an external process into a text widget

That's what test2.tcl in this [L1 ] "Regular Expressions" [L2 ] column does.

Also see the fileevent page.

The sample chapter 22 from Brent Welch's book can be downloaded from his home page and ( "TK Examples", or "TK by Example" ) [L3 ] also gives an example of this.


The link on top may not clarify this at a glance. I myself was thinking about opportunities with pipes and send, and how to handle remote command execution with both methods. See Playing with Pipes, Send and DDE - RJM

Reference to text widget.


Can anyone point to an example where a text widget displays the stdout and stderr from a command, as it is produced - not waiting until the execution finishes?

Rfox 3/8/2012 - This is done by the NSCLDAQ Readout Gui. The data taking program is a command driven program (Tcl Interpreter), the stdout and stderr of this program, which may be run over an ssh pipe, are captured in an output window as they occur as often experimenters will insert debugging output.

AMG: See How to run external script from Tk and make it throw output to the console? and [L4 ].

Tcl 8.4:

package require Tk
set shell csh
proc log {text {tags {}}} {
    .output configure -state normal
    .output insert end $text $tags
    .output configure -state disabled
    .output see end
}
proc transmit {} {
    global chan
    log "\$ [.input get]\n" input
    puts $chan [.input get]
    .input delete 0 end
}
proc receive {} {
    global chan
    log [read $chan]
}
entry .input
scrollbar .scroll -orient vertical -command {.output yview}
text .output -state disabled -yscrollcommand {.scroll set}
.output tag configure input -background gray
pack .input -fill x -side bottom
pack .scroll -fill y -side right
pack .output -fill both -expand 1
focus .input
set chan [open |$shell a+]
fconfigure $chan -buffering line -blocking 0
fileevent $chan readable receive
bind .input <Return> transmit

Tcl 8.6:

package require Tcl 8.6
package require Tk
set shell [list csh]
proc log {text {tags {}}} {
    .output configure -state normal
    .output insert end $text $tags
    .output configure -state disabled
    .output see end
}
ttk::entry .input
ttk::scrollbar .scroll -orient vertical -command {.output yview}
text .output -state disabled -yscrollcommand {.scroll set}
.output tag configure input -background gray
.output tag configure error -background red
pack .input -fill x -side bottom
pack .scroll -fill y -side right
pack .output -fill both -expand 1
focus .input
lassign [chan pipe] rderr wrerr
set stdio [open |[concat $shell [list 2>@ $wrerr]] a+]
foreach {chan tags} [list $stdio "" $rderr error] {
    chan configure $chan -buffering line -blocking 0
    chan event $chan readable [list apply {{chan tags} {
        log [chan read $chan] $tags
        if {[chan eof $chan]} {
            log EOF error
            .input state disabled
            chan close $chan
        }
    }} $chan $tags]
}
bind .input <Return> [list apply {{chan} {
    log [.input get]\n input
    chan puts $chan [.input get]
    .input delete 0 end
}} $stdio]

Jaj0 - 2017-03-02 16:15:42

Hi, i have issues with this code. I'm working on Windows and messages from STDOUT shows up in .output only when .exe command finishes. Here is my modified script:

package require Tk

proc log {text {tags {}}} {
    .output configure -state normal
    .output insert end $text $tags
    .output configure -state disabled
    .output see end
}
proc transmit {} {
    global chan
    log "\$ [.input get]\n" input
    puts $chan [.input get]
    .input delete 0 end
}
proc receive {} {
    global chan
    log [read $chan]
}
entry .input
scrollbar .scroll -orient vertical -command {.output yview}
text .output -state disabled -yscrollcommand {.scroll set}
.output tag configure input -background gray
pack .input -fill x -side bottom
pack .scroll -fill y -side right
pack .output -fill both -expand 1
focus .input
set chan [open "|micronucleus.exe --run --timeout 10" r]
fconfigure $chan -buffering line -blocking 0
fileevent $chan readable receive
bind .input <Return> transmit

I've tried many approaches to obtain this goal, but all showed STDOUT messages after .exe finishes