问题
Running our software will start a Tcl shell in Terminal, then we can execute a series of tcl commands in this Tcl shell by souce a tcl script file. But the tcl commands inside the tcl script file will not be printed on the Tcl shell, so, we cannot see what commands have been executed by source the tcl script.
So my question is, is there any configuration of Tcl can print out the commands in the script when the script been source.
Following is an sample tcl script
# sample.tcl, composed of 3 tcl commands:
read designfile
analyze
write output
If we interactively execute the 3 tcl commands in the Tcl shell, the result will be look as:
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"
If we source this tcl sript in Tcl shell, the result will be:
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"
We expect the the result will be as below when we source the script.
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"
回答1:
That's a job for an execution trace. These can be applied to all sorts of Tcl commands, not just procedures.
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
Note that this may print a lot more than you expect! Here's a more sophisticated version that prints only the outermost level of execution.
# 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"
}
}}}
回答2:
Thanks Donal very much! Based on his suggestion, finally I got the trace command as below to satisfy my requirment.
proc print {args} {
set cmd [lindex $args 0]
puts stdout "$> $cmd"
}
trace add execution source enterstep print
来源:https://stackoverflow.com/questions/63832193/when-source-a-tcl-script-in-tcl-shell-how-can-i-let-tcl-print-every-tcl-command