При отправке сценария Tcl в оболочку Tcl, как я могу позволить Tcl печатать каждую команду Tcl внутри сценария в оболочку?

#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. Обратите также внимание, что можно заменить эти лямбда-термины процедурами.