Comp.lang.tcl questioners '''frequently''' demand some sort of gadget to monitor-an-ongoing-process-and-display-the-result-in-a-[text]. [Tailing widget] is the simplest answer CL knows that meets the common intent of these requests. There are lots of variations on this theme, though. [tailf] carefully implements the functionality of the Unix tail(1), and adds a bit of filtering capability. I've written a few examples [http://phaseit.net/claird/comp.lang.tcl/tcl-examples.html#tail] that show how different combinations of IPC, fileevent, after, ... can co-operate to monitor continuing processes. A utility to filter the output of tail is [greptail]. It lazily uses the unix tail(1) program. Also see [directory notification package in Tcl] (Linux 2.4 and higher). And a more generic approach is outlined on the [file and directory change notifications] page. Here is another version. It continuously opens and closes the file and seems to work where a normal "tail -f" fails. This is the case at my internet provider's ssh-account (Linux infong159 2.4.24-grsec-20040109a). Issuing a "tail -f access_log" on the shell there will produce no output when I access the homepage, but using this little proc, I get instant response (well, within a second at least). I don't think this is a logfile-rotation issue, though: proc tail-f {filename} { # get an initial last position: set fh [open $filename r] seek $fh 0 end set pos [tell $fh] close $fh # ask again all second: while 1 { after 1000 set fh [open $filename r] fconfigure $fh -blocking no -buffering line seek $fh $pos start while {[eof $fh] == 0} { gets $fh line if {[string length $line] > 0} {puts $line} } set pos [tell $fh] close $fh } } ---- [[[MJ]]] To use this in a GUI (in the example above a call to tail-f will block) you can use the code below. This will also allow more tail windows per interpreter. proc tailf filename { # if toplevel already exists wait 2 seconds before retrying set now [clock seconds] set tl .$now if {[info commands $tl]!=""} { after 2000 [list tailf $filename] return } toplevel $tl wm title $tl $filename text $tl.t -width 60 -height 10 -yscrollcommand "$tl.scroll set" scrollbar $tl.scroll -command "$tl.t yview" pack $tl.scroll -side right -fill y pack $tl.t -side left set fp [open $filename] seek $fp 0 end set currpos [tell $fp] close $fp set mtime [file mtime $filename] read_more ${tl}.t $filename $mtime $currpos } proc read_more {widget filename oldmtime oldpos } { # check if the tail widget is not closed if {[info commands $widget] eq ""} { # tail window closed return } set mtime [file mtime $filename] set currpos $oldpos if {$mtime != $oldmtime} { set fd [open $filename r] seek $fd $oldpos start while {![eof $fd]} { $widget insert end [read $fd] } $widget see end set currpos [tell $fd] close $fd } after 1000 [list read_more $widget $filename $mtime $currpos] } # example usage tailf c:/test.log tailf c:/test2.log