当在 Tcl shell 中获取 Tcl 脚本时,如何让 Tcl 将脚本中的每个 Tcl 命令打印到 shell?

When source a Tcl script in Tcl shell, how can I let Tcl print every Tcl command inside the script to the shell?

运行我们的软件会在Terminal中启动一个Tclshell,然后我们可以在这个Tclshell中通过souce一个tcl脚本文件来执行一系列的tcl命令。但是tcl脚本文件里面的tcl命令不会打印到Tcl上shell,所以,我们看不到tcl脚本源代码执行了哪些命令。

所以我的问题是,有没有什么Tcl的配置可以在脚本是源代码的时候打印出脚本中的命令。

以下是一个示例 tcl 脚本

# sample.tcl, composed of 3 tcl commands:
read designfile
analyze
write output

如果我们在 Tcl shell 中交互执行 3 个 tcl 命令,结果将如下所示:

Tcl> read designfile
Info: reading designfile
Info: size: 128k
...
...
Tcl> analyze
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
Tcl> write output
Info: analyzed data been written into file "output"

如果我们在 Tcl shell 中获取此 tcl sript,结果将是:

Tcl> source sample.tcl
Info: reading designfile
Info: size: 128k
...
...
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
Info: analyzed data been written into file "output"

我们希望在获取脚本时得到如下结果。

Tcl> source sample.tcl
> read designfile
Info: reading designfile
Info: size: 128k
...
...
> analyze
Info: analyzing designfile
Info: 108 modules need to be analyzed
...
...
> write output
Info: analyzed data been written into file "output"

这是执行跟踪的工作。这些可以应用于各种 Tcl 命令,而不仅仅是过程。

trace add execution source enterstep {apply {{cmd op} {
    # Trim multiline commands down a bit; I find this helps me at least!
    regsub {\n.*} $cmd ... cmd
    # Print what's being run
    puts "EXECUTE: $cmd"
}}}
source thefile.tcl

请注意,这可能会打印出比您预期的多很多!这是一个更复杂的版本,它只打印最外层的执行。

# Called before [source] starts running
trace add execution source enter {apply {args {
    global SOURCE_LEVEL
    if {![info exists SOURCE_LEVEL]} {
        set SOURCE_LEVEL [info level]
    }
}}}
# Called after [source] finishes running
trace add execution source leave {apply {args {
    global SOURCE_LEVEL
    if {$SOURCE_LEVEL == [info level]} {
        unset SOURCE_LEVEL
    }
}}}
# Called for every command called while [source] is running
trace add execution source enterstep {apply {{cmd op} {
    global SOURCE_LEVEL
    if {$SOURCE_LEVEL == [info level]} {
        regsub {\n.*} $cmd "..." cmd
        puts "EXECUTE: $cmd"
    }
}}}

非常感谢多纳尔! 根据他的建议,我终于得到了如下的跟踪命令,满足了我的要求。

proc print {args} {
    set cmd [lindex $args 0]
    puts stdout "$> $cmd"
}

trace add execution source enterstep print