- Использовался и зачастую используется во многих сетевых устройствах – CheckPoint (web tcl), Cisco (tclsh), Ixia/Spirent (tcl automation api)
- Часто используется при проектировании FPGA (использование TCL скрипта позволяет избавить пользователя от рутинной работы по созданию проекта, добавлению новых файлов, обновлению IP-ядер и многих других однотипных вещей), с чем согласен из статьи:
- TCL – Tool Command Language, основной функцией языка TCL является автоматизация рутинных задач
- Интерпретатор TCL распространяется под свободной лицензией и доступен практически для всех платформ (во многих дистрибутивах Linux он доступен по умолчанию)
- На мой взгляд, главное удобство языка TCL заключается в том, что любой аргумент команды может быть заменен другой командой. Для этого его необходимо поместить в квадратные скобки.
- Название переменных корректнее в фигурные скобки заключать. Пример: puts ${NewValue}
- Комментировать большой кусок кода удобно конструкцией if 0 {… }
- Тиклевский скрипт эстетичней бить на иерархию: отдельно дефайны с конфигурацией, отдельно процедуры, и т.д. Для вызова вложений используется команда source inc_file.tcl
Разные полезности
- Вместо \n между разными командами можно использовать ; (one line команды)
- puts $::auto_path # вывод директорий, откуда берутся библиотеки
-
Загрузка в код переменных из файла конфигурации скрипта
-
source “c:/Users/test/Documents/App/script.tcl”
-
- break # stop execution
- return # завершение исполнения кода без выхода из wish console
- exit # с выходом
- after 10000 # execution sleep 10 сек –
after принимает время в миллисекундах
- IF
if {$fexist != 1} then { puts "Error! File $testfile not exists!" return }
- FOR
for {set iteration 1} {$iteration <= $testiterations} {incr iteration} { puts "===========" }
- Вывод всех переменных (включая библиотечных), некий аналог globals python.
# PRINT ALL VARIABLES foreach {x} [lsort [info globals]] { catch { puts "$x [subst $$x] " } err }
- Удаление файла
file delete -force $logfile
- Создание файла при отсутствии, открытие как append при наличии.
# CHECK & CREATE LOG FILE set fexist [file exist $logfile ] if {$fexist != 1} then { set logfile [open $logfile w] puts $logfile "Starting Test, script version: $scriptver" flush $logfile return } else { set logfile [open $logfile a+] }
- TCLx bsearch не распознает wildcard/regexp – поиск осуществляется только по полной строке
package require Tclx set f [open $resfilecsv] set res [bsearch $f "FULL_STRING_ONLY"]
- Реверсивное чтение возможно с использованием struct::list reverse – полезно, когда напр. нужно извлечь последнюю строку в большом файле. Сделал TCL функцию для этого.
# FAST EXTRACTION OF LAST LINE RES proc GetLastLine {resfilecsv} { mset fp [open $resfilecsv] set lines [split [read -nonewline $fp] "\n"] foreach line [struct::list reverse $lines] { return $line } } set res [GetLastLine $resfilecsv] puts $res
- Функция вывода логов на экран с timestamp (date + time) и записью всех логов в консоль
proc lg {str} { global logfile set timestamp [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}] puts "$timestamp: $str" puts $logfile "$timestamp: $str" flush $logfile }
- Может быть проблемой остановить execution в tcl, запускаемом в Windows/TCL. Стандартная функция gets зачастую не работает, proof 2. Решается вызовом внешнего скрипта (ниже пример).
I found how to get input from the user in the expect documentation, and I confirmed that Expect changes the blocking behavior of gets stdin
by testing. I was very surprised by that change.
Вызов внешнего скрипта
Может быть полезно внутри TCL вызывать какие-то утилиты.
В том числе таким образом обходится проблема с остановкой execution в TCL.
TCL code exec cmd.exe /c start /wait cmd_wait.exe CMD code @echo off echo press any key to continue the test pause>nul exit
list
- Сканим директорию и записываем в список все названия файлов с .exe.
set tstfiles [glob $testresdir/*.exe] puts $tstfiles
- Empty list
set a [list]
- Append
set a [list 4 3 2 1 15 6 29] lappend a 1 lappend a 10
- List Length
set ll [llength $a]
Математика
- ceil – к большему
- floor – к меньшему
Корректный расчет среднего не на сайте TCL (отсутствует truncate), а в stackoverflow .
proc average {l} { expr {[tcl::mathop::+ {*}$l 0.0] / max(1, [llength $l])} } Results (all): 33239.677 32198.674 37103.835 Results (avr): 34180.72866666667