[Arjen Markus] I read a question the other day on c.l.t. about tracing a script and I replied to a reply from Larry Virden, but while I misunderstood the question and his answer, I kept thinking "what does ksh -x actually do?" Then the light went on and I realised what I should have done, come up with a small script like the one below. While it is far from perfect (I have one script that seems to get stuck with it), it is a beginning. For the moment: here it is "as is". Maybe I will be able to perfect it later: * File names with paths are maltreated * Just puts the line is not very ingenious, you could write an interactive procedure for it instead, using something like [A minimal debugger], as shown in [Steppin' out]. ---- ====== # trace_script.tcl -- # Trace a script that is being executed # Usage: # tclsh trace_script.tcl script-to-run args # # namespace Trace -- # Private namespace # namespace eval ::Trace { variable traceOut stdout } # prepareLine -- # Prepare the line of code for output # # Arguments: # line Line of code # Result: # Line of code with [ and ] escaped # proc ::Trace::prepareLine {line} { string map {[ \\\[ ] \\\] \" \\\" \{ \\\{ \} \\\} } $line } # source -- # Redefine the source command to manipulate the source # of the script # # Arguments: # filename Name of the file to be sourced # Result: # Whatever the source file does # Side effects: # The manipulated source file is loaded # if {[info commands ::tcl::source] == {}} then { rename source ::tcl::source } proc source {filename} { set infile [open $filename "r"] set outfile [open TMP_$filename "w"] while { [gets $infile line] >=0 } { puts $outfile "puts \$::Trace::traceOut \"[::Trace::prepareLine $line]\"" puts $outfile $line } close $infile close $outfile ::tcl::source TMP_$filename file delete -force TMP_$filename } # main -- # Prepare argv and source the code # namespace import catch { console show } set filename [lindex $argv 0] set argv [lrange $argv 1 end] source $filename ====== ---- [MSW] says, nice :) I've taken the freedom to change the target of the rename to ::tcl::source and remove the temporary file later. [RS]: Writing a temporary file isn't necessary - just collect the "instrumented" code in a string variable and [eval] that. But I see a bigger danger: not every line contains a single command - sometimes it's less, or more. Consider ====== example with a long line that we want to continue \ on the next line set data { red green blue } ====== The [puts]es will be inserted both inside the 'example' command, and in the 'data' block, probably both leading to unexpected behavior. Better use [trace] execution, it's built in - see [Steppin' out] <> Debugging