0

文件1.txt

dut1Loop1Net = [::ip::contract [::ip::prefix 1.1.1.1/24]]/24  

我的脚本是

set in [open file1.txt r]  
set line [gets $in]  

if {[string trim [string range $line1 0 0]] != "#"} {  
    set devicePort [string trim [lindex $line1 0]]  
    set mark [expr [string first "=" $line1] + 1]  
    set val [string trim [string range $line1 $mark end]]  
    global [set t $devicePort]  
    set [set t $devicePort] $val  
}

close $in

问题

我得到的输出为

% set dut1Loop1Net

[::ip::contract [::ip::prefix 1.1.1.1/24]]/24

在这里,我得到字符串而不进行评估。
我期待输出为1.1.1.0/24. 因为 TCL 不在这里评估代码,所以它像字符串一样打印。

我很想知道 TCL 如何存储数据以及它将以何种形式检索数据。

4

2 回答 2

4

Tcl 如何存储值。

  • 短篇小说:

    一切都是字符串

  • 长篇大论

    Tcl 将数据存储在最后使用的数据类型中,仅在必要时计算字符串表示形式,使用写时复制,简单的引用计数内存管理。

您如何评估它的答案是evalsubst。在你的情况下可能subst

编辑:

如果您的配置文件如下所示:

# This is a comment
variable = value
othervar = [doStuff]

您可以使用一些技巧让 Tcl 为您解析它:

rename ::unknown ::_confp_unknown_orig
proc unknown args {
    if {[llength $args] == 3 && [lindex $args 1] eq "="} {
        # varname = value
        uplevel 1 [list set [lindex $args 0] [lindex $args 2]
        return [lindex $args 2]
    }
    # otherwise fallback to the original unknown
    uplevel 1 [linsert $args 0 ::_confp_unknown_orig]
    # if you are on 8.6, replace the line above with
    # tailcall ::_confp_unknown_orig {*}$args
}
# Now just source the file:
source file1.txt
# cleanup - if you like
rename ::unknown {}
rename ::_confp_unknown_orig ::unknown

另一种方法是使用安全的 interp,但在这种情况下,使用你的 main interp 看起来不错。

于 2013-09-03T10:45:36.120 回答
0

问题是你存储在里面的代码val永远不会被执行。

您可以使用 访问它$val,但这样您可以获得代码本身,而不是其执行的结果。

要解决它,您必须确保[::ip::contract [::ip::prefix 1.1.1.1/24]]/24已执行,您可以通过替换此行来做到这一点

set val [string trim [string range $line1 $mark end]]

有了这个

eval "set val [string trim [string range $line1 $mark end]]"

为什么?这是我的简单解释:

  1. 解析器看到该"..."部分,因此它在其中执行替换
  2. 第一个替换是string range $line1 $mark end命令的执行
  3. 第二个替换是string trim ...命令的执行

所以,当替换完成并且eval命令准备好运行时,就像你的行变成了

eval {set val [::ip::contract [::ip::prefix 1.1.1.1/24]]/24}

现在eval命令被执行,它递归地调用解释器,所以字符串set val [::ip::contract [::ip::prefix 1.1.1.1/24]]/24进入另一个替换阶段,最终运行你想要的并将字符串1.1.1/24放入变量val中。

我希望这有帮助。

于 2013-09-03T10:45:06.230 回答