在tcl中使用外部变量

时间:2014-06-23 09:55:21

标签: tcl

我有一个生成编号文件的脚本..

像这样:

set no 0

file fn [open log_file_$no w]

我想在每次运行脚本时记住这个no,即第一次运行时,文件名应为log_file_0,第二次应为log_file_1等。

有没有办法记住"变量的值,以便以后可以使用?

2 个答案:

答案 0 :(得分:1)

您不需要变量,您在文件列表中拥有所需的数字:

set no [scan [lindex [lsort -dictionary [glob log_file_*]] end] log_file_%2d]

incr no

set fn [open log_file_$no w]

让我们稍微突破一点。创建日志文件列表:

set filelist [glob log_file_*]

按字典顺序对列表进行排序(其中10位于2之后)并选择最后一个元素:

set highest_numbered [lindex [lsort -dictionary $filelist] end]]

从文件名中提取数字:

set no [scan $highest_numbered log_file_%2d]

增加号码并打开新的日志文件:

incr no
set fn [open log_file_$no w]

如果可能没有日志文件,glob命令将失败。要处理这种情况,请执行以下操作:

set filelist [glob -nocomplain log_file_*]
if {[llength $filelist]} {
    set highest_numbered [lindex [lsort -dictionary $filelist] end]]
    set no [scan $highest_numbered log_file_%2d]
} else {
    set no 0
}
incr no
set fn [open log_file_$no w]

或这个稍微安全的版本(如果你有Tcl 8.6):

try {
    glob log_file_*
} on ok filelist {
    set highest_numbered [lindex [lsort -dictionary $filelist] end]
    set no [scan $highest_numbered log_file_%2d]
} trap {TCL OPERATION GLOB NOMATCH} {} {
    set no 0
} on error message {
    puts stderr "error when listing log files: $message"
    set no -1
}
if {$no > -1} {
    incr no
    set fn [open log_file_$no w]
    # ...
    chan close $fn
}

文档:changlobifincrlindexlsortopen,{{3 }},scanset

(注意:' Hoodiecrow'在别处提到的是我,我之前使用过那个昵称。)

答案 1 :(得分:1)

您需要以某种方式将值存储到磁盘。 Hoodiecrow为您提供了一种明智的方法:在实际文件名中。其他选择:

  1. 在某个配置文件中
  2. 在数据库中(sqlite对此有利)

  3. (1)的演示

        # read the value
        if {[file exists num.dat]} {
            set fh [open num.dat r]
            set no [read -nonewline $fh]
            close $fh
        } else {
            set no 0
        }
    
        set logfile log_file_${no}
    
        # ...
    
        # write the value
        set fh [open num.dat w]
        puts $fh [incr no]
        close $fh
    

    (2)的演示

        package require Tcl 8.6
        package require tdbc::sqlite3
    
        set config_file config.db
        tdbc::sqlite3::connection create db $config_file
    
        # read the value
        if {[file exists $config_file]} {
            set stmt [$db prepare "create table config (number integer)"]
            $stmt execute
            $stmt close
            set no 0
        } else {
            set stmt [$db prepare "select number from config limit 1"]
            $stmt foreach row {
                set no [dict get $row number]
            }
            $stmt close
        }
    
        # ...
    
        # write the value
        set stmt [$db prepare "update config set number=:new limit 1"]
        $stmt execute [dict create new [incr no]]
        $stmt close
    
        $db close