我如何在TCL脚本中使用input.properties文件,如概念

时间:2013-04-08 10:00:50

标签: tcl

在ANt脚本中,我们访问属性文件,如下所示 <property file="input.properties"/> 在perl脚本中,我们访问属性文件,如下所示 do "config.cfg";

同样如何在TCL脚本中访问属性文件。 任何人都可以帮助我吗? 提前谢谢......

3 个答案:

答案 0 :(得分:2)

好的,如果你想要像Perl一样愚蠢,只需source Tcl中的文件。

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

# Set "foo" variable:
set foo bar

要加载此配置文件:

source config.tcl

source之后,您可以在脚本中访问变量foo


与perl一样,恶意用户可能会添加类似

的内容
exec rm -rf ~

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

答案 1 :(得分:0)

最简单的机制是使其成为脚本或使其成为数组的内容。以下是如何在仍然支持评论的情况下执行后者:

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
}

主目录中有一个文件(名为myapp.props),如下所示:

# 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

安全性开销很低。

答案 2 :(得分:0)

相当于perls

$var = "test";

在Tcl

set var "test"

因此,如果您希望它像Perl一样简单,我建议kostix answer


但您也可以尝试使用dicts作为配置文件:

这看起来像

var {hello world}
other_var {Some data}
foo {bar baz}

我个人喜欢使用它,它甚至允许嵌套:

nestedvar {
    subvar {value1}
    subvar2 {value2}
}

评论: 一种黑客攻击,实际上有一个键#

# {This is a comment}

解析:

 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解决方案也会这样做)。