Перейти к содержимому

Как запустить tcl скрипт

  • автор:

Скрипт на Tcl с ключом запуска

Я тут бестолково наваял пару скриптов на Tcl. Все работало ой как хорошо, но таки понадобилось запускать Tcl скрипт с ключом, напр. ./myprog.tcl 99.

Дальше смешно — сейчас у меня параметр для скрипта передается вот так:

В скрипте, соответственно,

Подскажите, как должна выглядеть программа на Tcl, чтобы её можно было запускать как ./myprog.tcl 99.

anonymous
10.09.07 19:35:15 MSD

Re: Скрипт на Tcl с ключом запуска

Есть глобальные переменные argc (число аргументов), argv (список аргументов).

man tclvars в общем.

Vadim_Z ★
( 10.09.07 19:58:32 MSD )
Ответ на: Re: Скрипт на Tcl с ключом запуска от Vadim_Z 10.09.07 19:58:32 MSD

Re: Скрипт на Tcl с ключом запуска

А в какую сторону man? Proc? Я что-то ни разу не программист. Так, иногда, прилады всякие.

anonymous
( 10.09.07 21:00:23 MSD )
Ответ на: Re: Скрипт на Tcl с ключом запуска от anonymous 10.09.07 21:00:23 MSD

Re: Скрипт на Tcl с ключом запуска

Дословно, man tclvars
Оно не как параметры передается, а как глобальные переменные.
С глобальными переменными работать умеем?

Грубо говоря,
if < $argc >0 > <
set sessa [lindex $argv 0]
>

Vadim_Z ★
( 10.09.07 22:02:44 MSD )
Ответ на: Re: Скрипт на Tcl с ключом запуска от Vadim_Z 10.09.07 22:02:44 MSD

Re: Скрипт на Tcl с ключом запуска

The following variables are only guaranteed to exist in tclsh and wish executables:

argc The number of arguments to tclsh or wish. argv Tcl list of arguments to tclsh or wish.

Я бездарность 🙂 Говорила мне мама не выпендриваться и писать скрипты на shell. Все скрипты стали короче на пару сотен строк. А в чертовых буржуйских книжках написано так, словно это абстрактные названия параметров.

anonymous
( 11.09.07 08:39:56 MSD )

Re: Скрипт на Tcl с ключом запуска

Хаа.. Госсподи, я твой код наверное на wtf программисткий скину 🙂 Чесна первый раз вижу чтоб в тикле чел сначала разобрался с каналами и пайпами а потом с argc :))))))))

Как запустить tcl скрипт

Когда Интерпретатор запустится, он сочтет все три строки комментариями, потому что обратный слеш в конце второй строки означает для него, что третья строка есть продолжение комментария на второй строке.

Изменить символ приглашения можно при помощи переменных tcl_prompt1 и tcl_prompt2. Если переменная tcl_prompt1 существует, то она должна содержать скрипт Tcl для вывода приглашения; вместо вывода своего приглашения, ⌠Интерпретатор■ будет исполнять скрипт в tcl_prompt1. Переменная tcl_prompt2 используется аналогичным образом, когда при вводе была начата новая строка, но вводимая команда еще не была закончена. Если переменная tcl_prompt2 не была задана, то для незаконченных команд не будет выводиться никакого приглашения.

Все права защищены 1992-1999 DataX/FLORIN, Inc.
Ваши пожелания и предложения принимаются вебмастером

Уроки Tcl

Tcl может использоваться как средство для связи разных программ между собой. Например, как .bat файлы DOS или shell-скрипты в Unix. Так же как в .bat файлах, вы можете вызывать другие программы из Tcl. Запущенные программы называются подпроцессами.

Есть два способа создать подпроцесс из Tcl:

  • open — запускает новую программу, прикрепляя её ввод и вывод к файловому дескриптору.
  • exec — просто создаёт подпроцесс.

Вызов open аналогичен открытию файла. Если первый символ имени файла символ потока (|), то open запустит программу, прикрепив ввод и вывод к файловому указателю. Он может быть открыт для чтения, записи, или чтения/записи.

Многие операционные системы буфферизуют ввод и вывод. Это значит, что строка, которую вы посылаете командой puts может не отправиться сразу, а будет записана в буфер. Когда буфер заполнится (или будет выполнена команда flush), то будет непосредственно выведена. При обычном запуске буфер очищается после каждой команды, однако при использовании потоков между программами для повышения эффиктивности буфер накапливает большие порции информации.

Если файл открыт для чтения и записи вы должнты знать, что потоки буферизованы. Следует периодически использовать команду flush, чтобы иметь уверенность, что данные посланы подпроцессу. Выходные данные так же не будут доступны для чтения read или gets, пока буфер подпроцесса не будет заполнен.

Вызов exec аналогичен обычному запуску программы (или нескольких программ) из командной строки. Поддерживается несколько способов перенаправления вывода, или вы можете получить вывод подпроцесса как возвращаемое значение команды exec.

open |имяПрограммы ?доступ?
Возвращает указатель на файл. имяПрограммы должно начинаться с символа потока (|). Если имяПрограммы заключено в кавычки или фигурные скобки, то может включать аргументы для подпроцесса.
exec ?ключи? арг1 ?арг2? . ?аргN?
Exec воспринимает арг1 как имя запускаемой программы, а остальные аргументы — аргументы для неё. Ключи начинаются с «-» и могут устанавливать некоторые параметры выполнения:
-keepnewline — Оставляет завершающие символы начала новой строки. (обычно они удаляются)
— (два минуса) — Обозначает конец ключей. Следующий аргумент будет воспринят как имя программы, даже если начинается с минуса («-«).

Арг1 — аргN команды exec могут быть следующими:

  • имя программы, которую нужно выполнить, подпроцесс
  • аргументами для подпроцесса
  • команды перенаправления ввода/вывода

Есть много разнообразных команд перенаправления ввода/вывода. Вот основной набор этих команд:

|
Поток вывода команды, предшествующей символу потока перенаправляется на стандартный ввод следующей команды.
< имяФайла
Первая программа потока будет читать ввод не из консоли, а из фала имяФайла
< @ указФайла
Первая программа потока будет читать из указателя на файл указФайла, который действителен в Tcl программе. УказФайла — значение возвращаемое командой open . «r».
Первая программа потока получит значение как входной поток.
> имяФайла
Вывод последней программы потока будет перенаправлен в файл имяФайла. Предыдущее содержимое файла будет потеряно.
>> имяФайла
Вывод последней программы потока будет добавлен к содержимому файла имяФайла.
2> имяФайла
Стандартный вывод ошибок всех программ потока будет послан в файл имяФайла. Предыдущее содержимое этого файла будет потеряно.
2>> имяФайла
Стандартный вывод ошибок всех программ потока будет добавлен в файл имяФайла.
>@ указФайла
Вывод последней программы в потоке будет записан в указФайла. УказФайла — значение, возвращаемое командой open . «w».

Есть несколько вещей, которые нужно помнить при использовании exec и open.

  • Если вы используете Tcl для программирования скриптов, или вводите команды прямо в интерпретатор, то нет нужнды использовать кавычки для группировки слов.
  • Если вы используете конструкцию open |cmd «r+», то после каждой команды puts нужно использовать flush.
    Так же можно использовать команду fconfigure, чтобы сделать канал не буферизованым.
  • Если одна из команд в open |cmd не сработает, то open не возвратит ошибку. Однако, при попытки чтения из файлового указателя с помощью gets $file возвратит пустую строку. Ипользование gets $file input возвратит число символов -1.
    Исправьте в примере строку «Эта строка придёт назад.» на «Эт», чтобы увидеть этот случай в примере.
  • Если одна из команд при вызове exec не сработает, то exec вернёт ошибку.

Код примера демонстрирует как использовать open и exec в паре. Это не лучший способ, но рабочий. В частности, если вы передаёте большой текст, то обычно использовать exec с перенаправлением на указФайлов быстрее.

Пример начинается с записи простой программы Tcl, которая исправляет порядок символов во временном файле. Эта программа будет запущена отдельно, для проверки записи и чтения в отдельной программе.

Как только программа записана и файл закрыт, мы можем запустить Tcl скрипт. Команда:

set io [open «|$tempFileName» r]

открывает поток для чтения и записи в новую программу. Когда строка передана в программу, следует команда flush.

Когда Tcl скрипт прочитает строку из stdin (стандартный поток ввода), он исправляет порядок символов на обратный, и записывает в stdout (стандартный поток вывода), и завершает работу. Когда программа завершает — буфер очищается, и программа примера читает выходную строку из канала.

Пример с командой exec показывает другой способ работы программы. Одна лстрока ввода может быть послана другой программе одной командой Tcl.

Пример:

# Создание уникального имени для файла set tempFileName "test[pid].tcl" # Открывает файл и записывает туда программу set outfl [open $tempFileName w] puts $outfl < set len [gets stdin line] if  for = 0>  < append l2 [string range $line $i $i] >puts $l2 exit 0; > # Сбрасывает данные и закрывает файл flush $outfl close $outfl # Запускает подпрограмму из текущей и # Открывает поток к программе set io [open "|tclsh $tempFileName" r+] # посылает строку новой программе # *Данные должны быть сброшены flush* puts $io "Эта строка вернётся назад." flush $io # Получает ответ set len [gets $io line] puts "До инверсии: 'Эта строка вернётся назад.'" puts "Инвертированная строка: $line" puts "Строка содержит $len символов" # Запуск программы с заданной строкой на входе set invert [exec D:/PROGRA~1/Tcl/bin/tclsh.exe $tempFileName 
Горбачев "Yurez" Юрий

Tcl для Cisco IOS в простых примерах

Представим, что вам нужно развернуть «с нуля» десяток однотипных access-коммутаторов Cisco. Типовая конфигурация включает имя хоста и домена, шлюз по-умолчанию, пароли, список пользователей, IP-адреса для SVI, номера VLAN'ов, настройки транков аплинков и т.д. Вводить это каждый раз руками очень долго и непроизводительно. Разумеется, можно создать типовой конфиг и заливать его по (T)FTP, но, во-первых, это потребует хотя бы минимальной настройки из консоли, во-вторых, изменяемые параметры конфигурации всё равно придётся менять. Для решения подобных (а также многих других) задач Cisco IOS содержит мощное средство автоматизации — встроенный интерпретатор языка Tcl (Cisco IOS scripting w/ Tcl).

Что такое Tcl

Tcl (читается «тикль», иногда «текл») — интерпретируемый язык программирования, разработанный в конце 80-х для встраивания в консольные приложения. Спектр возможностей современного Tcl довольно широк: тут и поддержка ООП, и развитые средства regexp, динамические массивы и т.д.

Реализация этого языка в устройствах Cisco имеет несколько вариантов:

  • Интерпретатор Tcl с интерфейсом командной строки. Встроен в разные версии платформы Cisco IOS, включая IOS XE и XR и доступен для широкой линейки устройств. Позволяет выполнять команды Tcl, запускать готовые скрипты в виде файлов и т.д. Устройства, использующие в качестве операционной системы не IOS а, например, Cat OS или ASA (в одноименном брандмауэре) командной строки интерпретатора не содержат.
  • Т.н. «встроенный менеджер событий» или EEM — система отслеживания событий, позволяющая автоматически на них реагировать в режиме реального времени. Например, осуществлять мониторинг удаленного хоста с уведомлением по e-mail. EEM-сценарии (аплеты) пишутся на Tcl, но сам EEM не предоставляет отдельной командной строки Tcl. Пример использования см. тут. EEM доступен на платформе Nexus (NX OS) и ASA с версии 9.2(1) и выше.
  • Системы голосового меню IVR (Interactive Voice Responce).

image

Пункт меню Research Features позволяет выбрать конкретную версию IOS для заданного IOS Train Release или конкретной аппаратной платформы. Пункт меню Research Software позволяет найти все версии IOS с поддержкой Tcl для заданного hardware. Кликаем, фильтруем поле Filter by по названию (Feature name) «Cisco IOS scripting w/ Tcl» (или просто «Tcl»), название фичи добавляем в список, выбираем Train release и получаем список всех версий IOS, содержащих данную фичу:

К сожалению, база CFN неполная и иногда не показывает всю информацию. Так, для платформы CAT2960S навигатор показал наличие Tcl в релизе IOS 15.2E1 и не показал в релизе 15.2E9, хотя по факту интерпретатор Tcl есть и там, и там.

Что же можно сделать в Cisco IOS используя Tcl? Довольно много: просматривать и изменять конфигурацию, создавать интерактивные сценарии, оперировать объектами MIB и даже… написать целый веб-шелл!

В общем виде программа на языке Tcl содержит последовательность команд, разделенных переводом строки или точкой с запятой. Пример, не требующий пояснений:

 puts "Hello, world!"; puts "My first Tcl IOS script!"

# комментарий до конца строки
set a 1 приcвоение a=1
$a получение значения переменной
< >блочный оператор — определяет тело цикла или условия
[ ] оператор подстановки — при выполнении вместо квадратных скобок будет подставлено вычисленное значение содержащегося в них выражения
== операторы сравнения
puts "text" вывод строки «text» в stdout (т.е., на консоль)
puts $a аналогично для значения переменной a
gets stdin читает значения из консоли
set a [gets stdin] ввод значения из консоли и присвоение его переменной a
for <. >цикл for

Более полный список см. progopedia.ru/language/tcl

Интерпретатор Tcl запускается командой tclsh из priveleged EXEC-режима:

sw#Tclsh sw(tcl)#

Выполним первый скрипт:

image

Tcl чувствителен к регистру, поэтому Puts "Hello, world" вызовет ошибку, а вот регистр команд оболочки IOS неважен. Все вводимые команды сначала обрабатываются интерпретатором Tcl, если введенная команда является исполнимой с т.з. Tcl, она исполняется и результат выводится на устройство TTY. Если команда не может быть выполнена интерпретатором, она передается парсеру команд IOS. Т.о., один скрипт может комбинировать операторы Tcl и команды IOS. Cреда IOS не содержит полноценного текстового редактора, поэтому pre-defined скрипты нужно создавать внешними средствами и уже потом копировать на flash или в память. Запуск файла со скриптом на выполнение осуществляется командой

tclsh flash:filename

Допустимы множественные сеансы интерпретатора Tcl из разных сессий TTY.

Внутренние команды интерпретатора Tcl:
exec — выполняет заданную в кавычках команду из набора IOS CLI priveleged EXEC.
sw(tcl)#exec "show int fa0" выдаст:

image

ios-config — выполняет команду из global configuration mode. За ней в отдельных парных кавычках указываются все последующие команды sub-configuration. Например:
sw(tcl)#ios_config "int fa0" "ip address 192.168.0.1 255.255.255.0" "no shut"
эквивалентно серии команд IOS:

sw#conf te sw(config)#int fa0 sw(conf-int)#ip address 192.168.0.1 255.255.255.0 sw(conf-int)#no shut

Тикль не поддерживает типизацию, это надо помнить, оперируя с переменными:

image

Вложенный оператор [expr ] вычислит значение выражения, заданного в фигурных скобках ($a + $b) и выполнит подстановку этого значения вместо квадратных скобок.

Теперь перейдем к решению практической задачи. Перед нами 48-ми портовый Cat2950S «из коробки». Скрипт, приведенный ниже

  • запрашивает с консоли порядковый номер свича sw_num
  • задает для него hostname вида switch_
  • запрашивает и устанавливает пароль на консоль priveleged EXEC
  • настраивает в соответствии с введенным номером свича адрес на его интерфейсе управления Fa0 (192.168.0.х) и интерфейсе Vlan1 (10.0.х.254)
  • создает port-based DHCP reservation и пул из 48 адресов, в котором за каждым клиентом зарезервирован один IP-адрес, младший октет которого равен порядковому номеру порта, через который это клиент подключен.
puts "Enter Switch number:" set sw_num [gets stdin] ios_config "hostname switch_$sw_num" puts "Enter password (secret):" set pass [gets stdin] ios_config "enable secret 0 $pass" ios_config "line 0 16" "password 0 $pass" "login" ios_config "int fa0" "ip address 192.168.0.$sw_num 255.255.255.0" "no shut" ios_config "int vlan1" "ip address 10.0.$sw_num.254 255.0.0.0" "no shut" ios_config "ip dhcp use subscriber-id client-id" ios_config "ip dhcp subscriber-id interface-name" #перебираем в цикле все 48 портов и для каждого задаем опцию subscriber-id for    ios_config "ip dhcp pool POOL1" "network 10.0.0.0 255.0.0.0" "reserved-only" "default-router 10.10.0.254" # записываем в пул 48 зарезервированных IP-адресов, привязанных к соотв. порту for    #

Примечание 1. В этом скрипте есть небольшая логическая ошибка. Попробуйте её найти.

Примечание 2. Некоторые текстовые редакторы любят помещать в конце файла непечатаемый символ EoF. Его можно увидеть в консоли IOS, выведя содержимое файла командой cat или more. Наткнувшись на EoF, интерпретатор Tcl выдаст ошибку и проигнорирует всю строку. Поэтому я оставил в конце скрипта экранирующий знак комментария.

Возникает вопрос: а как же записать скрипт в память коммутатора с ненастроенным IP работая только через консольный порт? Не набирать же скрипт руками! Неужели каждый раз вручную настраивать Management Interface и пользоваться FTP? Нет, можно проще. Cisco IOS умеет копировать файлы прямо через последовательный порт консоли по протоколу Xmodem и сохранять их на флеш. Для этого вам понадобится эмулятор терминала с поддержкой Xmodem, например, ZOC или Tera Term (а вот популярный бесплатный Putty, увы, не подойдет!). Копирование выполняется командой IOS copy xmodem: flash:filename , после чего нужно выполнить File Transfer в меню эмулятора терминала:

image

Также это можно сделать находясь в ROMmon (например, если вы «сносите» конфиг коммутатора, не имея пароля на priveleged EXEC). А вот обратное копирование файлов (с флэш-памяти коммутатора на ПК) не поддерживается.

На этом краткий экскурс в возможности языка Tcl на платформе Cisco IOS завершен, изучить вопрос более подробно вы можете в документе «Cisco IOS Scripting with TCL Configuration Guide» доступном на сайте Cisco.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *