当在 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
运行我们的软件会在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