#tcl
#tcl
Вопрос:
Запуск нашего программного обеспечения запустит оболочку Tcl в терминале, затем мы сможем выполнить серию команд tcl в этой оболочке Tcl, создав файл сценария tcl. Но команды tcl внутри файла сценария tcl не будут напечатаны в оболочке Tcl, поэтому мы не можем видеть, какие команды были выполнены исходным кодом сценария tcl.
Итак, мой вопрос в том, есть ли какая-либо конфигурация Tcl, которая может распечатывать команды в сценарии, когда сценарий был исходным.
Ниже приведен пример сценария tcl
# sample.tcl, composed of 3 tcl commands:
read designfile
analyze
write output
Если мы интерактивно выполним 3 команды tcl в оболочке 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 в оболочку Tcl, результат будет:
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"
Ответ №1:
Большое спасибо Доналу! Основываясь на его предложении, наконец, я получил команду трассировки, как показано ниже, чтобы удовлетворить мое требование.
proc print {args} {
set cmd [lindex $args 0]
puts stdout "$> $cmd"
}
trace add execution source enterstep print
Комментарии:
1. Вы должны добавить это в качестве комментария и отметить ответ Донала как принятый.
2. Да, я хочу, но когда я добавляю комментарий, я не знаю, как отобразить мои коды в комментарии.
Ответ №2:
Это задание для трассировки выполнения. Они могут применяться ко всем видам команд 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"
}
}}}
Комментарии:
1. Я протестировал это с помощью различных
package require
операторов, и тогда я понял, что вторая версия, вероятно, действительно необходима, чтобы избежать генерации тысяч строк ненужного вывода.2. Спасибо, Донал! Но, похоже, «применить» не может быть распознано. Когда я отправляю файл tcl, он сообщает: недопустимое имя команды «применить»
3. Обновите свой Tcl, поскольку
apply
вам требуется не менее 8.5, лучше перемотать до 8.6.4. Если у вас нет apply , это означает, что вы используете неподдерживаемую версию Tcl. Версии 8.4 и более ранние больше не поддерживаются вообще. Обновление.
5. Обратите также внимание, что можно заменить эти лямбда-термины процедурами.