在一个可执行的TCL脚本中,我正在定义一个我想要在另一个可执行的TCL脚本中导入的变量。在Python中,可以通过在一个脚本底部使用以下习语来组合库和可执行文件:
# Library
if __name__ == "__main__":
# Executable that depends on library
pass
TCL有同等的东西吗? There is for Perl
答案 0 :(得分:6)
Tcl的等价物是将::argv0
全局变量与info script
命令的结果进行比较。
if {$::argv0 eq [info script]} {
# Do the things for if the script is run as a program...
}
::argv0
全局(技术上是标准tclsh
和wish
shell的一项功能,或其他在C级调用Tcl_Main
或Tk_Main
的功能)具有主脚本的名称,或者如果没有主脚本则为空字符串。 info script
命令返回当前正在评估的文件的名称,无论是source
还是因为主shell将其作为脚本运行。当前脚本是主脚本时,它们将是相同的。
正如mrcalvin在下面的评论中指出的,如果您的库脚本有时用于未设置argv0
的上下文(自定义shell,子解释器,嵌入式解释器,某些应用程序服务器等),那么您应该添加先做一点检查:
if {[info exists ::argv0] && $::argv0 eq [info script]} {
# Do the things for if the script is run as a program...
}
答案 1 :(得分:1)
我最近希望该功能为我的HDL构建脚本套件设置一些单元测试。这就是我最终为Vivado所做的事情:
proc is_main_script {} { ;# +1 frame
set frame [info frame [expr [info frame] -3]]
if {![dict exists $frame file]} {
set command [file normalize [lindex [dict get $frame cmd] 1]]
set script [file normalize [info script]]
if {$script eq $command} {
return 1
} else {
return 0
}
} else {
return 0
}
}
if {is_main_script} { ;# +1 frame
puts "do your thing"
}
在测试/演示时,我认为主要用例是文件末尾带有if {is_main_script} {puts "do something"}
“未嵌套”的行。
如果需要使它更通用,可以为frame
引用-3
开发一个动态句柄。到目前为止,所有这些都涵盖了我的所有用例。
frame
-3
用作proc
,if
创建了额外的帧,并对此进行评估,我们希望在此之前检查呼叫。
dict exists
用于检查框架中是否存在file
。这将表明该调用来自更高层次的脚本,并且不会存在“ main_script”
如果以if {[info exists ::argv0] && $::argv0 eq [info script]}
运行,解决方案vivado -source TCLSCRIPT.tcl
效果很好,但是上面的解决方案涵盖了gui或tcl模式下的source TCLSCRIPT.tcl
(这是我调试自动化tcl时经常做的事情)。
我想这是一个小众案例。但是由于找不到这个问题的其他解决方案,因此我想将其留在这里。