如何在TCL中跟踪日志文件

时间:2011-11-28 21:16:57

标签: linux logging tcl tail

假设有一个文件log.txt,并且会永久地附加某种日志。

我想在TCL环境中跟踪该文件。

我试过这个,但没效果。

set log [open log.txt a]

for { } { true } { update; after 1000 } {

    # expected to get here the appended part
    read $log

    seek $log 0 end

}

是否可以通过相同的文件句柄log读取修改后的文件,或者我必须关闭并重新打开文件log.txt

在TCL中是否有一种等效的Linux命令tail -f

3 个答案:

答案 0 :(得分:4)

只需使用tail即可。它更了解你如何处理复杂的案例(你可以查看它的来源)。

在我的一个项目中,我有类似的东西来监视由专有工具生成的跟踪文件:

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]
     }
  }
}

一般的想法是你在给定文件上生成tail然后输入事件循环并逐行处理tail的输出。

答案 1 :(得分:0)

你并不遥远,只需要修理一些事情:

  1. 在这段代码中,您正在从文件中读取,而不是附加到它,其他一些进程将会这样做,因此应该以读取模式打开文件,而不是追加模式,即。从open命令中删除“a”选项。
  2. 在开始阅读之前,您应该只搜索文件的一端,否则您将跳过稍后添加的内容,因此请在循环之前移动搜索命令。
  3. 在发布的代码中,您没有对您阅读的文本做任何事情 - 我将举例说明将其写回stdout。
  4. 如果您在循环中的处理涉及更新gui或需要事件循环的其他内容,则只需要update命令 - 发布的代码不需要它。 这总共给出了:

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

答案 2 :(得分:0)

我设法在纯Tcl上写tail -f等价物。代码如下:

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