Purpose: provide a mechanism for displaying the end of a file.
proc setup filename { text .t -width 60 -height 10 -yscrollcommand ".scroll set" scrollbar .scroll -command ".t yview" pack .scroll -side right -fill y pack .t -side left set ::fp [open $filename] seek $::fp 0 end } proc read_more {} { set new [read $::fp] if {$new ne ""} { .t insert end $new .t see end } after 1000 read_more } setup logfile read_more # Notice this is portable code. # An industrial-strength version would probably exploit # namespaces ...
Arjen Markus What is not so obvious from the above code, is that there is no easy way to tell whether the process responsible for writing the file that is tailed has finished or not. So, it is not a solution (alas) for monitoring the output of a program that writes to file and then finishes.
DKF 11Dec02 - There's no way to tell that anyway. And in any case, the process writing the file might not be on the same computer either.
People often ask for a way to 'pipe' from an external process into a text widget.
[MJ] The version below will 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 -expand 1 -fill both 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 {![winfo exists $widget]} { # 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