【问题标题】:Fullpath of current TCL script当前 TCL 脚本的全路径
【发布时间】:2010-10-01 11:08:19
【问题描述】:

有没有可能得到当前正在执行的TCL脚本的完整路径?

在 PHP 中是:__FILE__

【问题讨论】:

    标签: tcl


    【解决方案1】:

    根据您所说的“当前正在执行的 TCL 脚本”的含义,您实际上可能会寻找 info script,甚至可能是 info nameofexecutable 或更深奥的东西。

    【讨论】:

      【解决方案2】:

      获取当前语句所在文件名的正确方法是这样(真正等同于 PHP/C++ 的__FILE__):

      set thisFile [ dict get [ info frame 0 ] file ]
      

      伪代码(如何工作):

      1. set thisFile <value> :将变量 thisFile 设置为 value
      2. dict get <dict> file :从字典中返回文件值
      3. info frame <#> :返回一个dict,其中包含有关指定堆栈级别(#)的帧的信息,0 将返回最近的堆栈帧 注意:有关信息框架的更多信息,请参阅帖子末尾。

      在这种情况下,从info frame 返回的file 值已经标准化,因此不需要file normalize <path>。

      info script 和info frame 之间的区别主要是用于 Tcl 包。如果info script 用于在包需要期间提供的 Tcl 文件 (require package <name>),则 info script 将返回当前正在执行的 Tcl 脚本的路径,并且不会提供包含的 Tcl 文件的实际名称info script 命令;但是,此处提供的info frame 示例将正确返回包含该命令的文件的文件名。

      如果您想要当前正在评估的脚本的名称,那么:

      set sourcedScript [ info script ]
      

      如果您想要最初调用的脚本(或解释器)的名称,那么:

      set scriptAtInvocation $::argv0
      

      如果您想要最初调用的可执行文件的名称,那么:

      set exeAtInvocation [ info nameofexecutable ]
      

      更新 - 详细信息:info frame

      这是 Tcl 中堆栈跟踪的样子。 frame_index 向我们展示了 info frame $frame_index 对于从 0 到 [ info frame ] 的值的样子。

      调用info frame [ info frame ]在功能上等同于info frame 0,但使用0当然更快。

      实际上只有1 到[ info frame ] 堆栈帧,0 的行为类似于[ info frame ]。在这个例子中你可以看到0和5(也就是[ info frame ])是一样的:

      frame_index: 0 | type = source | proc = ::stacktrace | line = 26 | level = 0 | file = /tcltest/stacktrace.tcl | cmd = info frame $frame_counter
      frame_index: 1 | type = source | line = 6 | level = 4 | file = /tcltest/main.tcl | cmd = a
      frame_index: 2 | type = source | proc = ::a | line = 2 | level = 3 | file = /tcltest/a.tcl | cmd = b
      frame_index: 3 | type = source | proc = ::b | line = 2 | level = 2 | file = /tcltest/b.tcl | cmd = c
      frame_index: 4 | type = source | proc = ::c | line = 5 | level = 1 | file = /tcltest/c.tcl | cmd = stacktrace
      frame_index: 5 | type = source | proc = ::stacktrace | line = 26 | level = 0 | file = /tcltest/stacktrace.tcl | cmd = info frame $frame_counter
      

      见: https://github.com/Xilinx/XilinxTclStore/blob/master/tclapp/xilinx/profiler/app.tcl#L273

      【讨论】:

      • info frame 0 应该足够了,而不是更长的info frame [ info frame ]。零表示当前帧,而最里面的info frame 不带参数将返回当前帧的编号。
      • 嗨@cfi,这有点违反直觉,但是 [ info frame ] 真的从 1 开始并转到 [ info frame ]。 1 是发起呼叫,[ info frame ] 是最近的呼叫。但是,如果您将 0 传递给 info frame,那么您将获得相当于 [info frame [info frame]],这是最近一次调用。
      【解决方案3】:

      你想要$argv0

      【讨论】:

      • 如果从过程访问,要么将 argv0 定义为全局,要么将其完全限定为 $::argv0
      • 请注意,全局变量argv0 是tclsh 和wish(以及tclkit)的一个特性,而不是一般的Tcl。不过这很常见;支持函数Tcl_Main 为您实现它……
      【解决方案4】:

      您也可以使用 [file normalize] 来获取完全规范化的名称。

      file normalize $argv0
      file normalize [info nameofexecutable]
      

      【讨论】:

        【解决方案5】:

        在我发布我的问题几秒钟后...lindex $argv 0 是一个很好的起点 ;-)

        【讨论】:

        • 我想你会对此感到失望。您将获得文件名之后的第一个参数。如果您执行“tclsh foo.tcl one two”,则 argv 将是一个类似 ["one" "two"] 的列表
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-13
        • 1970-01-01
        • 1970-01-01
        • 2016-05-19
        • 2010-11-14
        • 1970-01-01
        • 2012-01-21
        相关资源
        最近更新 更多