How to track log file in TCL

Let's say that there is a log.txt file, and some kind of log is constantly being added to it.

I want to track this file in a TCL environment.

I tried this, but it did not work.

 set log [open log.txt a] for { } { true } { update; after 1000 } { # expected to get here the appended part read $log seek $log 0 end } 

Is it possible to read the modified file with the same log file descriptor, or do I need to close and reopen the log.txt file?

Is there any equivalent to the Linux tail -f command in TCL?

+6
source share
3 answers

Just use tail . He knows more that you are on how to handle complex cases (you can look at its source).

In one of my projects, I have something like this in order to track the trace file created by the proprietary tool:

 set fd [open [list | tail --follow=name --retry --lines 0 $opt(trace) 2>@1]] chan event $fd readable [list FollowTrace $fd] proc FollowTrace fd { if {[gets $fd line] < 0} { set code [catch {close $fd} err] if {$code == 0} { set ::result 0 } else { puts stderr $err set ::result 1 } return } switch -regexp -matchvar parts -- $line { {Tm_Session::Open.*FileName=([^,]+)} { TryMakeLock [FullPathname [lindex $parts 1]] } {Tm_Session::Close.*FileName=([^,]+)} { StartUpload [lindex $parts 1] } } } 

The general idea is that you create tail in the given file, then enter the event loop and tail process output line by line.

+4
source

You are just around the corner, just a few corrections:

  • In this code, you are reading from a file, and not adding it, some other process will do it, so it should open the file in read mode, and not in add mode, i.e. uncheck the "a" option from the open command.
  • You should search only the end of the file once before you start reading, otherwise you will skip the material that will be added later, so move the search command before the loop.
  • In the published code, you are not doing anything with the text you are reading - I will give an example by simply returning it to stdout.
  • You only need the update command, if your processing in the loop includes updating the gui or something else that requires an event loop - this is not required for the submitted code. In general, this gives:

     set log [open log.txt] seek $log 0 end for { } { true } { after 1000 } { # expected to get here the appended part puts -nonewline [read $log] } 
0
source

I managed to write the tail -f equivalent in pure Tcl. Code below:

 proc readHandler {handle} { puts -nonewline [read $handle] flush stdout # to reduce CPU overhead... after 1000 } set hFile [open "file.log" "r"] # seek to the end of file if needed # seek $hFile 0 end fconfigure $hFile -buffering none -eofchar "" -blocking no fileevent $hFile readable [subst {readHandler $hFile}] #just for exiting into main event loop vwait forever 
0
source

Source: https://habr.com/ru/post/902593/


All Articles