如何在TCL脚本中使用类似concept的input.properties文件

如何在TCL脚本中使用类似concept的input.properties文件,tcl,Tcl,在ANt脚本中,我们访问属性文件如下 在perl脚本中,我们访问属性文件,如下所示 do“config.cfg” 同样,我如何访问TCL脚本中的属性文件。 有人能帮我吗? 提前感谢…最简单的机制是将其作为脚本或数组的内容。下面是如何在支持评论的同时实现后者: proc loadProperties {arrayName fileName} { # Put array in context upvar 1 $arrayName ary # Load the file c

在ANt脚本中,我们访问属性文件如下
在perl脚本中,我们访问属性文件,如下所示
do“config.cfg”

同样,我如何访问TCL脚本中的属性文件。 有人能帮我吗?
提前感谢…

最简单的机制是将其作为脚本或数组的内容。下面是如何在支持评论的同时实现后者:

proc loadProperties {arrayName fileName} {
    # Put array in context
    upvar 1 $arrayName ary

    # Load the file contents
    set f [open $fileName]
    set data [read $f]
    close $f

    # Magic RE substitution to remove comment lines
    regsub -all -line {^\s*#.*$} $data {} data

    # Flesh out the array from the (now clean) file contents
    array set ary $data
}
然后你会这样使用它:

loadProperties myProps ~/myapp.props
if {[info exists myProps(debug)] && $myProps(debug)} {
    parray myProps
}
# Turn on debug mode
debug true
# Set the foos and the bars
foo "abc"
bar "Harry's place downtown"
在您的主目录中有一个文件(名为
myapp.props
),如下所示:

loadProperties myProps ~/myapp.props
if {[info exists myProps(debug)] && $myProps(debug)} {
    parray myProps
}
# Turn on debug mode
debug true
# Set the foos and the bars
foo "abc"
bar "Harry's place downtown"
你可以做比这复杂得多的事情,但它提供了一个简单的格式


如果您喜欢使用可执行配置,只需执行以下操作:

# Define an abstraction that we want users to use
proc setProperty {key value} {
    # Store in a global associative array, but could be anything you want
    set ::props($key) $value
}
source ~/myapp_config.tcl
如果要将操作限制在不会造成(太多)麻烦的操作上,则需要一种稍微复杂一点的方法:

interp create -safe parser
proc SetProp {key value} {
    set ::props($key) $value
}
# Make a callback in the safe context to our main context property setter
interp alias parser setProperty {} SetProp
# Do the loading of the file. Note that this can't be invoked directly from
# within the safe context.
interp invokehidden parser source [file normalize ~/myapp_config.tcl]
# Get rid of the safe context; it's now surplus to requirements and contaminated
interp delete parser

安全性具有相当低的开销。

好的,如果您希望它像Perl中一样愚蠢,只需使用Tcl中的
source
文件即可

配置文件示例(名为
config.tcl
):

要加载此配置文件,请执行以下操作:

source config.tcl
source
-ing之后,您可以访问脚本中的变量
foo


与perl一样,恶意用户可能会

exec rm -rf ~

在您的“配置文件”中,祝您好运。

相当于perls

$var = "test";
在Tcl

set var "test"
因此,如果您想让它像Perl一样简单,我建议


但您也可以尝试将其用作配置文件:

这看起来像

var {hello world}
other_var {Some data}
foo {bar baz}
我个人喜欢使用它,它甚至允许嵌套:

nestedvar {
    subvar {value1}
    subvar2 {value2}
}
和评论:有点像黑客,实际上有钥匙
#

解析:

 set fd [open config.file]
 set config [read $fd]
 close $fd
 dict unset config #; # Remove comments.
访问:

 puts [dict get $config var]
 puts [dict get $config nestedvar subvar]

但是如果你真的想要像
$var=“foo”(这是有效的Perl代码,但不是Tcl),然后您必须自己解析这个文件

例如:

proc parseConfig {file} {
    set fd [open $file]
    while {[gets $fd line] != -1} {
         if {[regexp {^\s*\$([^\s\=]+)\s*\=\s*(.*);?$} $line -> var value]} {
              # The expr parses funny stuff like 1 + 2, \001 inside strings etc.
              # But this is NOT perl, so "foo" . "bar" will fail.
              set ::$var [expr $value]
         }
    }
}

缺点:不允许多行设置,如果存在无效值,将抛出错误,并允许命令注入(但您的Perl解决方案也可以这样做)。

您可以从属性加载程序设置全局变量,但这可能是个坏主意。如果加载脚本,您可能会考虑使用一个安全的解释器,它严格地显示了命令的暴露形式。或者你可能不麻烦;毕竟这是用户的应用程序,如果他们想破坏它,他们可以这样做。:-)我是Tcl新手,但就属性Gruop name和valsue访问而言,它似乎很复杂。在perl中,这很简单。只需在config.cfg文件中定义,如
$var=“test”
我们可以在脚本中使用户将该值指示为
print$var
,方法与我想在Tcl中使用的name=“value”相同。