IPLNMNG - описание языка скриптов

Общее описание

Программа IPLNMNG с версии 3.09 содержит в себе интерпретатор языка скриптов. Предназначен для облегчения обслуживания концентратора. Содержит в себе функции аналогичные ftp, удаленный запуск команд, средства обработки текстов и др. Для нормальной работы нужно чтобы на сервере был iplncfg 3.07 и выше. Часть команд скриптов доступна напрямую в меню "выполнить команду", для этого команда должна начинаться с '@'. В этом случае она рассматривается не как команда для выполнения на сервере а как команда скрипта.

Схема работы

При запуске скрипта командой script, указанный файл загружается в память.

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

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

Символ '#" считается признаком комментария. Все что стоит за ним не рассматривается( если символ '#' включен в апострофы при определении строки, он не рассматривается как признак комментария.

Если строка начинается с '+'  - то строка рассматривается как продолжение предыдущей строки. Обратите внимание, если вы поставите в конце предыдущая строка заканчивается комментарием, то новая строка будет продолжением комментария, а не оператором.

Если строка начинается с '.', то дальнейший текст рассматривается как имя файла которое надо включить в это место. Если файл с таким именем уже был включен, то строка игнорируется. 

Все пробелы в строке рассматриваются как разделители, если они не в апострофах, то несколько пробелов рассматриваются как один пробел.

Если строка начинается с $ (пробелы до игнорируются) - то строка рассматривается как подстановка оператора. При выполнении, она будет повторно проанализирована на код используемого в нем оператора. Нельзя таким образом подставлять имена процедур, метки, операторы организации циклов и ветвления. Пример подстановки оператора:

set oper="put"
if equ($rootfrom,1)
   set oper="get"
endif
$oper "$fn1" "$fn2"

Переменные и оператор set

Любая переменная прежде чем использоваться, должна быть создана оператором set. . Этот же оператор используется для изменения значения переменной. Часть переменных может быть создана оператором proc, этот способ будет описан позднее. 

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

Синтаксис оператора set

set [-<ключи>] <имя переменной>[<спецификатор массива>] [=] <значение>

<ключи>:

<имя переменной> - последовательность из букв и цифр длинной до 20-ти символов. Специальное значение имеют имена '0' - '9', используемые для доступа к параметрам скрипта, также могут использоваться для доступа к параметрам процедуры - но лучше использовать поименованные параметры.

<спецификатор массива> - [ {<строка>|<функция>] - задает индекс массива, а при первом присваивании - задает размер массива

[<значение>] = {<строка>|<функция>|<массив>}

<строка> - последовательность символов, если встречаются символы отличные от букв и цифр - должна быть заключена в кавычки  ' или ".  Если в кавычках встречается два символа кавычек, то они рассматривается как одинарный знак кавычки. Если знак кавычки внутри - отличен от используемого по краям, удвоение не нужно.

<функция> -  вызов внутренней функции, будут описаны ниже.

<массив> - список элементами которого могут быть строки или функции через запятую, заключенный в фигурные скобки {}. Используется для первичной инициализации массива.

Если написать оператор set без параметров он выведет все переменные и уровень вложенности вызовов процедур.

ЗАМЕЧАНИЕ: допускается обращение к обычной переменной  <имя переменной>[0], и к массиву без указания <спецификатор массива> (рассматривается как спецификатор [0]).

Видимость переменных

По умолчанию в процедуре оператор set создает локальную переменную. Это означает, что она будет видна в этой процедуре и во всех процедурах, которые будут вызваны из этой процедуры. На выходе из процедуры (по return или endproc) локальные переменные уничтожаются. 

С точки зрения процедур, вызываемых из этой процедуры, эта переменная внешняя. Она доступна по умолчанию на чтение и подстановку, но, если ее нужно изменить, требуется задать ключ -e. Если ключ не задать, то будет создана новая локальная переменная с таким же именем. 

Каждый оператор call создает новый пул локальных переменных. 

Оператор script  также создает новый пул локальных переменных, но в отличие от call, он скрывает все не глобальные переменные, которые были объявлены до его вызова.

Глобальные переменные доступны везде, ключ -g требуется только при первом создании переменной. Если при этом задать еще ключ -s, то переменная будет сохранятся в конце сеанса и восстанавливаться при новом сеансе с этим сервером. Если используется способ назначения переменной через оператор proc, то он может временно скрыть глобальную переменную для процедур нижнего уровня.

Подстановка переменных

Чтобы вместо переменной было подставлено ее значение, нужно перед именем переменной поставить $. Чтобы имя переменной выделялось правильно(например если за именем сразу идет текст без пробела, можно использовать комбинацию $(<имя переменной>). Подставленная переменная может использоваться в любом месте строки( внутри строк, для вызываемых имен функций, процедур, меток перехода). Нельзя использовать как метку и как имя процедуры в операторе proc

Если нужно использовать символ $ в строке, то нужно писать $$.

Есть ограничение при подстановке элементов массива. Не допускается комбинация когда индекс массива сам является подставляемой переменной. В этом случае надо использовать промежуточное присвоение.

Интерпретатор рассматривает все пробелы вне кавычек, как разделители. При этом несколько пробелов подряд, с его точки зрения как один пробел. Нужно учитывать эту особенность при использовании подстановки. Пример:

set a="     xxx    "
set b=$a
set c="$a"

В результате таких операций значение переменной b будет "xxx", а переменная с будет равна переменной a. Если же переменная a была "  xxx   yyy  ", то значение переменной b,  все равно было бы "xxx", и вы бы получили предупреждение о непонятных данных в строке. 

Аналогичные ситуации могут быть и с другими специальными символами, поэтому  там где надо используйте кавычки.

Операции с переменными

Кроме подстановки, для манипуляции  с переменными используется набор встроенных функций. Сами функции будут описаны ниже. Отличие встроенных функций от процедур (создаваемых оператором proc), что они могут использоваться непосредственно в операторе set и в качестве параметров для вызова других функций и процедур. Процедуры могут вызываться только оператором call.

Примеры

Примеры назначения переменных:

set     name="c:\ut\tools"
set     i=0
set     -a  array[10]            # Выделить массив на 10-ть элементов
set     -a a[5] = {x,y,z}       # Выделить массив и первые 3 элемента проинициализировать
set     i=add($i,1)              # Присвоить i значение i+1  
set     -gs path="/sbin:"    # создать сохраняемую глобальную переменную 
set     -e name=""c:\ut\x"  #изменить внешнюю переменную name     
set     name="$(name)x"   # изменить значение name на значение $name+x

Передача управления

Метки

Для передачи управления на какую либо команду скрипта используются метки. Некоторые опера торы используют неявное назначение меток, поэтому метки начинающиеся с "_" лучше не использовать. Синтаксис:

:<имя метки>

<имя метки> -  может быть до 20-ти символов. На метку можно передавать управление оператором goto или оператором call. Если управление передается call параметры передаваемые в операторе call доступны по именам 0 - 9, но лучше этот кусок кода оформлять как процедуру .  При вызове оператором call управление передается назад оператором return.

Оператор proc

Оператор proc используется для оформления процедур. Не допускается описание одной процедуры в другой. Если по ходу выполнения встречается описание процедуры, то управление получает строка следующая за концом процедуры. Синтаксис:

proc <имя>[([<параметр-1>[, ...,<параметр-n>],][<список>])[:<minp>[:<maxp>]]]

<имя> - имя процедуры длинной до 20-ти символов.

<параметр-n> - <имя параметра-n>[:<список типов>:[<мин>]:макс]]

<имя параметра-n> - задает имя параметра, по которому к нему можно обращаться.  Работать с ним аналогично как и с обычной переменной.

<список типов> - можно указать тип параметра. Если тип задан, то параметр проверяется на соответствие этому типу. Допускаются следующие типы:

Тип 'p' может сочетаться с другими типами. Переменная типа 'f' всегда должна быть указателем и для нее 'p' не надо указывать. Если проверка типа не прошла, то выполнение скрипта завершается аварийно. Если вы допускаете, что на входе могут идти неправильные данные, то вы должны не указывать тип и контролировать его сами.

[<мин>]:<макс> - для целочисленных параметров можно указать диапазон, в каком должен находится параметр. При несоответствии - действия аналогичные как при несовпадении типа.

<список> - список локальных переменных. При передаче управления процедуре всегда выделятся память под максимальное число параметров (10). Если число параметров меньше 10, то остальным переменным в стеке тоже можно присвоить имена и работать с ними как с локальными переменными(не может быть переменной типа массива). Причем лучше всего здесь размещать наиболее часто используемые переменные, так как поиск всегда начинается с этого списка. Общее число параметров и переменных из этого списка не должно превышать 10.

<minp>[:<maxp>]  - задает минимальное и максимальное число параметров, которое должно передаваться процедуре. Если число параметров в call не соответствует этому диапазону, выполнение скрипта прекращается.

Замечание-1: если имя одного из параметров или переменной из <список>,  совпадает с именем глобальной переменной, то он скрывает доступ к этой переменной.

Замечание-2: переменные передаваемые процедуре доступны также по именам 0 - 9,  но лучше это не использовать, тогда при изменении параметров вызова процедуры не нужно будет переделывать ее тело.

Примеры:

proc deltree(dir:s,deldir:i:0:1, rc,root,sep,seppos,fn,fhl,fn2,line):1:2
proc load_ulist(wfile:s,apkt:a,ipkt:ip,afiles:a,ifiles:ip,adeps:a,ideps:ip,mode:i:0:1, fh,fn):7:8
proc varpath(fn,line,fh,fok,wpath,pos1,pos2,linetmp,pathtmp):0:0
proc grep_next(fh:f,str:s,line:ps,case:i:0:1, fok,case2):3:4

Оператор return

Оператор возвращает управление на оператор, следующий за командой call. Если это головной скрипт, то происходит завершение выполнения скрипта. Синтаксис:

return [<код возврата>]

<код возврата>  - код возврата процедуры. допускается только целочисленное значение. В вызывающей программе  код может быть проверен функцией lastrc() или error(). 

Оператор endproc

Оператор обозначает конец кода процедуры.  Синтаксис:

endproc

Если выполнение процедуры дошло до оператора endproc, то он работает аналогично return без кода возврата.

Оператор goto

Оператор используется для перехода на какую либо метку. Синтаксис:

goto <метка>

<метка>  - имя метки, которой передается управление. Если метка не существует, то выполнение завершается аварийно. Допускается подстановка имени метки. Пример :

goto $lab

будет выполнен переход на метку которая содержится в переменной lab.

Оператор call

Оператор используется для вызовов процедур. Синтаксис:

call <имя>[([[<параметр-1>,]...<параметр-n>])]

<имя> - имя метки или процедуры. Допускается подстановка  имени переменной.

<параметр-n> - параметр передаваемый процедуре. Может быть переменной,  строкой или внутренней функцией. Для переменных может передаваться как значение (используя оператор подстановки "$"), так и адрес переменной, если перед ее именем стоит "&"

Важное: Если передается адрес переменной, то допускается модификация переменной в вызываемой процедуре и любое изменение параметра в ней, приводит к изменению параметра в вызывающей процедуре. Если процедура попытается изменить параметр который не имеет тип указателя, будет выдано предупреждение об этом.

Примеры:

call grep_next(&fh, "PATH=",&line)
call get_cur_distr_ver("%FD_ROOT%",&sver,&kver)
call rename_distr("old","new")
call $next

Оператор script

Оператор служит для вызова выполнения скриптов. Синтаксис:

script <имя> [[<параметр-1>,]...<параметр-n>]

<имя> - имя скрипта. Если указан полный путь, то за имя берется он без изменения, если указано только короткое имя, берется файл с таким именем и расширением .sc из директории script.

<параметр-n> - параметр передаваемый для скрипта. Задается также как и в операторе call. Отличие в том, что если это вызов головного скрипта, в нем допускаются только параметры типа строки.

Передача параметров

Еще раз обобщенное описание о передаче параметров:

Организация циклов

Для организации циклов используется операторы while и enddo, а также оператор продолжения цикла continue и оператор прерывания цикла break. Синтаксис:

while  [!]<условие продолжения>
...
[continue]
...
[break  [[!]<условие выхода>]]
...
enddo

<условие продолжения> - задает выражение, определяющее условие продолжения. Если результат выполнения будет равен '1' цикл продолжается, при любом другом - цикл прерывается.

<условие выхода> - задает выражение, определяющее условие выхода. Если результат выполнения будет равен '1' цикл прерывается.

Если стоит символ '!' перед условием, то это означает, что нужно инвертировать условие (оператор "not").

Если оператор break без условия, то цикл прерывается всегда. При встрече оператора continue управление получает оператор while. Операторы break и continue могут стоять в любом месте внутри цикла.

Максимальная вложенность циклов 10.

Пример 1:  организация цикла типа for:

set i=0
while lt($i, $ifinst)
    ...
    set i=add($i,1) 
enddo

Пример 2: организация цикла чтения файла и поиска строки:

set ok=0
while 1
    set line=readlf(&fh)
    break eof(&fh)
    set ok=at(&line,&str,$case)
    break gt($ok,0)
enddo

Организация ветвления

Для ветвления используются операторы if, elif, else, endif. Синтаксис: Синтаксис:

if  [!]<условие-1>
...
[elif [!]<условие-2>]
...
[elif [!]<условие-n>]
...
[else]
...
endif

<условие-n> - задает выражение, определяющее условие при котором управление получает следующий за текущим оператор. Если результат выполнения будет равен '1'  - условие считается истинным, иначе получает управление следующий оператор elif, else или endif.

Если стоит символ '!' перед условием, то это означает, что нужно инвертировать условие (оператор "not").

Максимальная вложенность операторов if один в другой равна 10.

Внимание: обратите внимание, условие считается выполненным только, если значение равно символьной '1', при любых других значениях ('0', '2' , "", "xxx"...) условие считается не выполненным.

Пример:

if equ($nsel,0)
    call save_iplncfg
elif equ($nsel,1)
    call save_allcfg
elif equ($nsel,2)
    call save_all
else
    echo "Не верный параметр"
endif

Операторы работы с файлами и директориями

Оператор get

Оператор get предназначен для получения файла с сервера на машину, где выполняется скрипт. Синтаксис:

get [<ключи>] <имя файла на сервере> [<имя файла на этой машине>]

<ключи>:

<имя файла на сервере> - имя файла которое надо скопировать. 

<имя файла на этой машине> - имя принимающего файла. В режиме append, идет добавление в конец файла. Если имя опущено, происходит копировка во временный файл и он выводится в окно данных.

Оператор put

Оператор put предназначен для записи файла с локальной машины на сервера. Синтаксис:

put [<ключи>] [-perm=ccc] <имя файла на этой машине> <имя файла на сервере> 

<ключи>:

-perm - установить права доступа ccc для файла на сервере

<имя файла на этой машине> - имя файла, который надо копировать

<имя файла на сервере> - имя файла куда надо скопировать. 

Оператор list

Оператор list предназначен для получения списка файлов и(или) директорий с сервера или локальной машины. Синтаксис:

list [-r<sel>] [<ключи>] <имя поддиректории> [<имя файла> [&<переменная>]]

<sel> - задает корневую файловую систему, для относительно которой выполняется команда:

<ключи>:

Если не задано ни "d" ни "f", берется и то и другое.

<имя поддиректории> - имя поддиректории для которой нужно выполнить команду 

<имя файла> - имя локального файла куда записать список. Если имя опущено, происходит копировка списка во временный файл и он выводится в окно данных.

<переменная> - если задана переменная то, к файлу со списком сразу открывается доступ для построчного чтения функцией readlf ().

Замечание: Программа iplncfg не предоставляла доступ к корневой файловой системой сервера, а только к директории /etc. Чтобы обеспечить совместимость со всеми версиями iplncfg, скрипт в директории /etc делает символическую ссылку с именем '!' на корень, а затем через нее работает с ним. Префикс '!' удаляется и добавляется автоматически из имени, также директория  '!'  удаляется из списка результатов.

Оператор mv

Оператор mv предназначен для переименования файлов(или директорий) на сервере или локальной машине.  Синтаксис:

mv <имя откуда> <имя куда>

<имя откуда> - полное имя файла или директории, которые надо переместить 

<имя куда> -  полное имя файла или директории, куда надо переместить(переименовать) 

И <имя откуда> и <имя куда> должны находится на одной машине (на сервере или на локальной). Тип машины определяется из имени файла.

Оператор rm

Оператор rm предназначен для удаления файла на сервере или локальной машине.  Синтаксис:

rm <имя> 

<имя> - полное имя файла, который надо удалить 

Тип машины определяется из имени файла.

Оператор mkdir

Оператор mkdir предназначен для создания директории на сервере или локальной машине.  Синтаксис:

mkdir <имя> 

<имя> - полное имя директории, которую надо создать 

Тип машины определяется из имени файла.

Оператор rmdir

Оператор rmdir предназначен для удаления директории на сервере или локальной машине.  Синтаксис:

rmdir <имя> 

<имя> - полное имя директории, которую надо удалить 

Тип машины определяется из имени файла.

Удаленное выполнение программ(оператор run)

Оператор run предназначен для выполнения команды на сервере и получении результатов ее выполнения. Синтаксис:

run  [<ключи>] <имя команды> "<параметры>" [{<имя файла> | &<переменная>}]

<ключи>:

<имя команды> - полный путь к команде на сервере 

<параметры> - параметры передаваемые программе

<имя файла> - если задано, то это имя локального файла куда записать результаты . 

<переменная> - если задана переменная то, к файлу с результатами выполнения сразу открывается доступ для построчного чтения функцией readlf (). Файл помечается как временный и при закрытии cloself(&<переменная>,1) - файл будет сразу удален.

Если не заданы ни имя переменной, ни файл, происходит копировка результатов во временный файл и он выводится в окно данных.

Оператор вывода echo

Оператор echo предназначен для вывода данных на экран и управления выводом. Окно сообщений командных процедур выглядит следующим образом:

IPLNMNG экран выполнения скриптов

Оператор echo позволяет выводить данные в разные части окна. Синтаксис:

echo [<ключи>] <данные>

<ключи>:

Если не заданы ключи 'c', 'e', 'h' - данные попадают в окно информационных сообщений и результатов (самое большое окно)

<данные> - любые данные, если встречаются имена функций, то происходит их вызов и подстановка результатов.

Внутренние функции

Все операции с переменными выполняются с помощью внутренних функций. В отличие от процедур, вызываемых только командой call, вызовы функций могут использоваться в операторах присвоения, в списках параметров оператора call, в качестве условия для операторов while, if, elif, break,  в данных оператора echo. При этом при интерпретации в строку на место вызова подставляется результат ее работы. Функции могут также вызываться оператором call , когда подстановка не нужна и если функция ничего не возвращает.

Механизм вызова внутренних функций аналогичен вызовом процедур и действуют те же ограничения. Максимальное количество параметров 10, максимальный уровень вложенности вызовов 20 (уровень вложенности включает в себя и процедуры и скрипты). Для многих функций параметры описаны аналогично оператору proc и, если контроль типа или числа параметров не прошел, в зависимости от ошибки, либо скрипт завершается аварийно, либо выводится предупреждение и предпринимаются действия по умолчанию.

В качестве параметров у функций могут быть  строки, переменные и другие функции.

Арифметические функции

Для всех функций в этом разделе параметры должны быть числами. Значение переменных хранится внутри в текстовом виде, перед операцией они преобразовываются в двоичный вид, затем производится операция и результат опять преобразовывается в символьный вид.

Результат выполнения функции показан в нотации  языка Си.

add - операция сложения

Синтаксис:

add(p0, p1[,p2,...[p9]])

Результат  p0+ p1+ ...+ p9. Минимальное число параметров 2. 

and - битовая операция "И"

Синтаксис:

and(p0, p1[,p2,...[p9]])

Результат  p0 & p1 &  ... & p9. Минимальное число параметров 2. 

div - операция деления

Синтаксис:

div(p0, p1)

Результат  p0 / p1.

equ - операция "равно"

Синтаксис:

equ(p0, p1)

Результат  (p0 == p1 ? "1" : "0" ).

gt - операция "больше"

Синтаксис:

gt(p0, p1)

Результат  (p0 > p1 ? "1" : "0" ).

gte - операция "больше или равно"

Синтаксис:

gte(p0, p1)

Результат  (p0 >= p1 ? "1" : "0" ).

lt - операция "меньше"

Синтаксис:

lt(p0, p1)

Результат  (p0 < p1 ? "1" : "0" ).

lte - операция "меньше или равно"

Синтаксис:

lte(p0, p1)

Результат  (p0 <= p1 ? "1" : "0" ).

mod - остаток от деления 

Синтаксис:

mod(p0, p1)

Результат  p0 % p1.

mul - операция умножения

Синтаксис:

mul(p0, p1[,p2,...[p9]])

Результат  p0*p1* ...* p9. Минимальное число параметров 2. 

notequ - операция "не равно"

Синтаксис:

notequ(p0, p1)

Результат  (p0 != p1 ? "1" : "0" ).

or - операция побитового сложения

Синтаксис:

or(p0, p1[,p2,...[p9]])

Результат  p0 | p1 |  ... | p9. Минимальное число параметров 2. 

sub - операция вычитания

Синтаксис:

sub(p0, p1[,p2,...[p9]])

Результат  p0 - p1 - ... - p9. Минимальное число параметров 2. 

Функции работы со строками

at - найти строку в подстроке

Синтаксис:

at(src, img[, cmpmode])

Ищет строку img в строке src. cmpmode - задает режим сравнения: 0 - case-чувствительное сравнение (по умолчанию), 1 - игнорировать регистр. 

Результат: 0 - если строка не найдена, иначе позиция подстроки img в строке src.

Примеры:

at("abcdefghij", "cd") - результат "3"
at("abcdefghij", "CD")- результат "0"
at("abcdefghij", "CD",1) - результат "3"
at("abcdefghij", "ij",1) - результат "9"

field - выделить поле из подстроки

Синтаксис:

field(src, num, [sep, [mode]])

Выделяет поле номер num в строке src. sep - задает символ разделитель полей (если не задан, подразумевается пробел). mode - задает режим обработки разделителей: если 1 - то несколько разделителей подряд рассматриваются как один разделитель (если не задан то 0). Нумерация полей начинается с 1.

Результат: если поле с заданным номером найдено, возвращается значение этого поля, иначе пустая строка.

Примеры:

field("aa bb cc dd",1) - результат "aa"
field("aa bb cc dd",2)
- результат "bb"
field("aa::bb::cc::dd",3,":")
- результат "bb"
field("aa::bb::cc::dd",3,":",1)
- результат "cc"

isnum - проверить что строка число

Синтаксис:

isnum(str,[mode]])

Проверяет является ли строка str числом. mode - если 0 (по умолчанию) то десятичное число, 1 - допускается шестнадцатеричное число (должно начинаться с 0x).

Результат: 1 - если проверка прошла.

equstr, strequ - операция "строки равны"

strequ и equstr синонимы одной и той же функции. Синтаксис:

equstr(str1, str2[, cmpmode] )

cmpmode - задает режим сравнения: 0 - case-чувствительное сравнение (по умолчанию), 1 - игнорировать регистр.

Результат: '1' - если строки str1 и str2 равны, иначе '0'

split - разбить строку на поля и записать в массив

Синтаксис:

split(&array[0], src, num, [sep, [mode]])

Разбивает строку на поля и каждое поле записывает в элемент массива. array - массив куда записать данные, num - сколько полей выбрать (должен быть меньше или равен размеру массива), src - исходная строка. sep - задает символ разделитель полей (если не задан, подразумевается пробел). mode - задает режим обработки разделителей: если 1 - то несколько разделителей подряд рассматриваются как один разделитель (если не задан то 0).

Результат: Возвращает число выбранных полей.

strcat - операция объединения строк

Синтаксис:

strcat(str0[, str1, ..., [str9]])

Результат: объединение строк str0 ... str9. Функцию с одним параметром можно использовать для копирование значения одной переменной в другую, если в ней имеются спец символы (например табуляция)

Примеры:

strcat("aa","bb") - результат "aabb"
strcat("aa",2,3,4) -
результат "aa234"

strcmp - операция сравнения строк

Синтаксис:

strcmp(str1, str2[, cmpmode] )

cmpmode - задает режим сравнения: 0 - case-чувствительное сравнение (по умолчанию), 1 - игнорировать регистр.

Результат: '0' - если строки str1 и str2 равны, "-1" - если str1 меньше str2, "1" - если str1 больше str2

strdup - операция размножения строки

Синтаксис:

strdup(str, num)

Результат: размножает строку str num раз.

Примеры:

strdup("a",3) - результат "aaa"
strcat("ab",2) -
результат "aa234"

strlen - операция длина
строки

Синтаксис:

strlen(str)

Результат: возвращает длину строки str .

strrep - операция замены символа в строке

Синтаксис:

strrep(src, char1[,char2])

Результат: заменяет в строке src все символы char1 на char2. Если char2 не задан или "", то происходит удаление всех символов char1 из подстроки

Примеры:

strrep("abc","a","b") - результат "bbc"
strrep("abc","a") -
результат "aa234"

sprintf  - операция форматирования

Функция используется для форматирования строк и для получения специальных символов. Не используйте в формате спецификаторы для чисел, т.к. все переменные внутри хранятся в символьном виде. 

Синтаксис:

sprintf(format[, p1,...[,p8]])

Результат: форматированная в соответствии с format строка. 

Примеры:

sprintf("\t") - результат знак табуляции
sprintf("%02s:%02s.%02s","1","10","8") -
результат "aa234"

substr - операция выделения подстроки

Синтаксис:

substr(src, pos, [len]])

Выделяет из строки src подстроку, начиная с позиции pos, и длинной len символов. Нумерация позиций начинается с 1. Если параметр len не задан, то берется подстрока до конца строки src.

Результат: подстрока. Если pos больше длинны строки то "".

Примеры:

substr("0123456789",4) - результат "3456789"
substr("0123456789",1,5) - результат "01234"
substr("0123456789",6,4) - результат "5678"
substr("0123456789",20,10) - результат ""

Функции работы со файлами

cloself - закрыть файл

Синтаксис:

cloself(&handle[,mode])

handle - переменная типа "Файл", полученная openlf, createlf или оператором list или run. mode - задает действие с файлом после закрытия. 0 - ничего не делать(по умолчанию), 1 - удалить файл, если он помечен как временный, 2 - удалить файл.

Результат: код возврата, который можно получить функцией lastrc(). Если 0 - то успех. Для вызова пользуйтесь командой call. Пример смотрите для openlf.

copy - скопировать файл

Синтаксис:

copy(filefrom,fileto[,mode])

Функция выполняет копирование файла filefrom в файл fileto на локальной машине. Если задан режим mode равный 1, то используется режим добавления. 

Результат: код врозврата. 

createlf - создать файл для записи в построчном режиме

Синтаксис:

createlf(filename,&handle)

Функция предназначена для создания файла filename для записи в построчном режиме. Файл может находится как на локальной машине, так и на сервере. Перед вызовом нужно присвоить переменной handle значение -1. На выходе, если операция прошла успешно, переменная изменит свой тип на тип "Файл". 

Результат: код возврата, который можно получить функцией lastrc(). Если 0 - то успех. Для вызова пользуйтесь командой call

eof - проверить конец файла

Синтаксис:

eof(&handle)

handle - переменная типа "Файл", полученная openlf, createlf или оператором list или run.

Результат: '1' - если файл закончился, иначе '0'.

exist - проверить что файл или директория существует 

Синтаксис:

exist(path[,&size])

Результат: '1' - path существует и является файлом, '2' - path существует и является директорией, '0' - path не существует. Если задана переменная size, то для файла туда будет записана его длина.

filename - выделить короткое имя файла

Синтаксис:

filename(path)

Результат: выделяет из пути path имя файла.

Пример:

filename("c:\xxx\yyy\name") - результат "name"
filename("/usr/local/bin/mod") -
результат "mod"

filetype  - получить тип файла

Синтаксис:

filetype(name)

Результат: возвращает '1' , если имя файла для сервера, иначе '0' 

fullpath - создать полный путь

Синтаксис:

fullpath(dirname, filename[, root])

Функция из dirname и filename создает полное имя файла относительно выбранного корня root("-1" авто определение(по умолчанию), другие допустимые значения как параметр -r в операторе list) . Один из параметров dirname или filename, может быть равен "". Кроме этого функция выполняет трансляцию имени на наличие в нем переменных %FD_ROOT%, %FD_BOOT%, %FD_ETC%, %FD_UPD% и если находит заменяет их на их значения.

Результат: сформированное имя файла.

Примеры:

fullpath("/xxx", "yyy") - результат "/xxx/yyy"
fullpath("/xxx", "yyy",1) - результат "/xxx/yyy"
fullpath("/xxx", "yyy",2) - результат "/mnt/fd/bootdisk/xxx/yyy"
fullpath("/xxx", "yyy",3) - результат "/mnt/fd/bootdisk/upgrade/xxx/yyy"
fullpath("/xxx", "yyy",4) - результат "/mnt/fd/xxx/yyy"
fullpath("%FD_BOOT%/xxx", "yyy") - результат "/mnt/fd/xxx/yyy"
fullpath("%FD_ROOT%/xxx", "yyy") - результат "/mnt/fd/bootdisk/xxx/yyy"
fullpath("%FD_UPD%/xxx", "yyy") - результат "/mnt/fd/bootdisk/upgrade/xxx/yyy"
fullpath("%FD_ETC%/xxx", "yyy") - результат "/mnt/fd/bootdisk/upgrade/etc/xxx/yyy"
fullpath("%FD_BOOT%","") - результат "/mnt/fd/"
fullpath("c:\xxx", "yyy") - результат "c:\xxx\yyy"

Замечание: реально вместо /mnt/fd будет подставляться значение в соответствии с версией дистрибутива на сервере.

maskequ - сравнить что имя файла соответствует маске

Синтаксис:

maskequ(mask, name[,cmpmode])

Функция проверяет удовлетворяет ли имя файла name заданной маске mask. Правила для маски такие: если  маска одна '*' - то ей удовлетворяют все имена, в прочих случаях '*' вызывает пропуск в имени файла всех символов, пока не встретится точка. Символ '?' в маске означает что на этом месте может быть что угодно. В остальных случаях символы маски и имени сравниваются в соответствии с cmpmode: 0 - case-чувствительное сравнение (по умолчанию), 1 - игнорировать регистр.

Результат: возвращает '1' , если имя удовлетворяет маске, иначе '0' 

mngdir - получить путь директории iplnmng

Синтаксис:

mngdir()

Результат: возвращает полный путь директории где находится iplnmng.

openlf - открыть файл для чтения в построчном режиме

Синтаксис:

openlf(filename,&handle)

Функция предназначена для открытия файла filename на чтение в построчном режиме. Файл может находится как на локальной машине, так и на сервере. Перед вызовом нужно присвоить переменной handle значение -1. На выходе, если операция прошла успешно, переменная изменит свой тип на тип "Файл". 

Результат: код врозврата, который можно получить функцией lastrc(). Если 0 - то успех. Для вызова пользуйтесь командой call

Пример: программа читает файл и выводит его в окно данных.

proc show_file(fn:s, fh, line):1:1
set fh=-1
call openlf(&fn,&fh)
if error()
   echo -e line()"Ошибка загрузки файла $fn, rc="hex(lastrc())
   return lastrc()
endif
while 1
    set line=readlf(&fh)
    break eof(&fh)
    echo "$line"
enddo
call cloself(&fh)
return 0
endproc

readlf - чтение файла в построчном режиме

Синтаксис:

readlf(&handle)

handle - переменная типа "Файл", полученная openlf, createlf или оператором list или run.

Результат: очередная строка файла. После выполнения нужно проверить закончился файл или нет функцией eof. Пример смотрите для openlf.

setfmark - пометить файл как временный

Синтаксис:

setfmark(&handle)

handle - переменная типа "Файл", полученная openlf, createlf или оператором list или run. Функция помечает данный фал как временный. В этом случае, при закрытии файла с о вторым параметром 1, он будет удален.

Результат: нет.  Для вызова пользуйтесь командой call

srvdir - получить путь директории сервера

Синтаксис:

srvdir()

Результат: возвращает полный путь директории приписанной серверу (<директория iplnmng>\servers\<ip-адрес сервера>).

tmpdir - получить путь временной директории

Синтаксис:

tmpdir()

Результат: возвращает полный путь временной директории.

tmpname - получить имя временного файла

Синтаксис:

tmpname()

Результат: возвращает полный путь уникального имени файла на локальной машине, который может использоваться как временный. При этом создается файл нулевой длины c этим именем.

writelf - запись в файл в построчном режиме

Синтаксис:

writelf(&handle, str)

handle - переменная типа "Файл", полученная openlf, createlf или оператором list или run. Производится запись строки str в файл. Строка дополняется символами конца строки, в соответствии с типом файла, поэтому добавлять их самим не надо. 

Результат: '1' - если строка успешно записана.

zerofile  - сделать длину файла 0

Синтаксис:

zerofile(path)

Результат: делает длину файла path равной 0. Файл может быть как локальный так и на сервере, тип определяется из имени.

Функции работы со меню и массивами

adel - удалить элемент массива

Синтаксис:

adel(&array, index)

Результат: удаляет элемент index в массиве  array. Индексация идет с 0. Для вызова пользуйтесь командой call

afill - заполнить массив

Синтаксис:

afill(str, cnt, &a1[,...[,a8]] )

Производит заполнение массивов a1 ... a8, размером cnt строкой str

Результат: нет

Для вызова пользуйтесь командой call

afind - поиск строки в массиве

Синтаксис:

afind(&array, count, str[, mode, [nf]])

Производит поиск строки а count элементах массива array. mode - режим сортировки: mode&1 - case-чуствительная сортировка или нет(если бит 1 задан), mode&2 -  нужно не полное совпадение, а включение строки str в элемент массива. По умолчанию mode равен 0. Если задан параметр nf, то поиск проводится по полю номер nf, разделитель полей при этом должен быть табуляцией

Результат: возвращает индекс элемента массива, -1 - если не найдено

asize - получить размер массива

Синтаксис:

asize(&array)

Результат: возвращает размер массива array. Используется для контроля индекса массива.

asort - сортировать массив

Синтаксис:

asort(&array, count, mode[, nf])

Производит сортировку count элементов массива array. mode - режим сортировки: mode&1 - case-чуствительная сортировка или нет(если бит 1 задан), mode&2 - по возрастанию или по убыванию(если бит 2 задан). По умолчанию mode равен 0. Если задан параметр nf, то сортировка проводится по полю номер nf, разделитель полей при этом должен быть табуляцией.

Результат: сортированный массив. Для вызова пользуйтесь командой call

input - ввести строку

Синтаксис:

input("Заголовок", "Подсказка", &var)

Выводит диалог с заданным заголовком и строкой подсказки. Переменная var, предназначена для получения результатов.

Результат: '1' - Если пользователь набрал текст, '0' - если отказался от операции.

item - получить элемент массива

Синтаксис:

item(&array[varindex])

Результат: возвращает значение элемента  массива, задаваемого переменной varindex. Интерпретатор не допускает двойной подстановки типа $array[$index]. Поэтому в таком случае можно использовать функцию item(&array[$index]).

menu  - организация меню

Синтаксис:

menu(&body[0], titlestr, items, &sel)

Организует выбор из меню, задаваемым массивом body. Строка titlestr выводится в заголовке. items - определяет число элементов в массиве. sel - на входе содержит текущий выбор, на выходе - сделанный новый выбор.

Результат: возвращает '1' , если пользователь сделал выбор, '0'  - если отказался.

Пример:

set items=20
set -a mb[$items]
set i=0
while lt($i, $items)
    set mb[$i]="item$i"
    set i=add($i,1)
enddo
set nsel=3
while menu(&mb[0],"Сделай выбор", $items,&nsel)
    echo "Сделан выбор $nsel"
enddo
echo "Сделан отказ"
return

srveditcfg - редактировать конфигурацию сервера

Синтаксис:

srveditcfg(path)

Вызывает программу редактирования конфигурации сервера. path - указывает на директорию содержащую конфигурационные файлы.

Результат: возвращает '1' , если пользователь подтвердил операцию, иначе '0' 

xlist - организация списка

Синтаксис:

xlist(titlestr,&tcols[0],&wcols[0],&actions[0], &body[0], ncols, items, &sel)

Организует выбор из меню, задаваемым массивом body. Строка titlestr выводится в заголовке. Каждый элемент массива состоит из нескольких полей, разделенных знаком табуляции, каждое поле выводится в отдельную колонку. tcols - массив заголовков колонок, wcols - массив ширины колонок (по умолчанию выравнивание в колонках вправо, если задать отрицательную длину, то колонка  выравнивается влево, 0-я колонка всегда влево), ncols - число колонок. items - определяет число элементов в массиве. sel - на входе содержит текущий выбор, на выходе - сделанный новый выбор. actions - массив доступных действий (не более 4-рех).

Результат: возвращает выбранное пользователем действие, при этом sel содержит текущий выбор в массиве body.

Пример:

#############################################
# Скрипт для выбора и просмотра журнала настройки #
#############################################
set rescan=1
set -a alog[120]
set -a atit[2] = {"Журнал", "Размер"}
set -a awtit[2] = {-200,70}
set -a aact[4] = {"Назад", "Просмотреть", "Удалить", ""}
set tit="Доступные журналы"
set nsel=0
while 1
if $rescan
   set fn=""
   set fcnt=0
   call create_flist("/var/log", "ipln*.log",&fn,&fcnt,0)
   if error()
      return
   endif
   if equ($fcnt,0)
      echo "Нет журналов"
      rm "$fn"
      return
   endif
   set fh=-1
   call grep_open(&fn,&fh)
   if !lastrc()
      rm "$fn"
      return -1
   endif
   set i=0
   while 1
      set line=readlf(&fh)
      break eof(&fh)
      set alog[$i]=strcat(&line)
      set i=add($i,1)
      enddo
      set rc=lastrc()
      call grep_close(&fh)
   endif
   if gte($nsel, $fcnt)
      set nsel=sub($fcnt,1)
   endif
   set action=xlist("$tit",&atit[0], &awtit[0], &aact[0], &alog[0],2, $fcnt, &nsel )
   break equ($action,0)
   set fnlog=field(item(&alog[$nsel]),1,sprintf("\t"))
   if equ($action,1)
      get -i "$fnlog"
      continue
   endif
   if equ($action,2)
      rm "$fnlog"
      set rescan=1
      rm "$fn" 
      continue
   endif
   break
enddo
rm "$fn"
return
###########
. lib\grep
. lib\flist

yesno - запросить подтверждение "да" или "нет"

Синтаксис:

yesno("сообщение")

Результат: возвращает '1' , если пользователь выбрал "Да", иначе '0' 

Прочие функции

constat - получить состояние связи с сервером

Синтаксис:

constat()

Результат: возвращает '1' , если связь с сервером установлена, иначе '0' 

date - получить дату и время

Синтаксис:

date()

Результат: возвращает дату и время в виде DD/MM/YY hh:mm:ss, DD - день, MM - месяц, YY - год, hh - часы, mm - минуты, ss - cекунды (пример: 08/07/2004 19:20:54 ).

error  - проверить, что код возврата не 0

Синтаксис:

error()

Результат: возвращает '1', если код выполнения последнего оператора или функции не 0.

hex - перевести число в шестнадцатеричную запись 

Синтаксис:

hex(num)

Результат: значение числа num преобразованную в шестнадцатеричную форму

lastrc - получить код возврата последней операции

Синтаксис:

lastrc([num])

Результат: возвращает код выполнения последнего оператора, если задан параметр num, то он замещает текущий код возврата на значение num .

line  - получить имя файла и номер текущей
строки

Синтаксис:

line()

Результат: строка вида <имя файла>:<номер строки>. Используется для улучшения диагностики ошибок.

msglevel  - управление уровнем сообщений

Синтаксис:

msglevel([num])

Результат: возвращает текущие уровень сообщений и, если задан параметр num, то он замещает уровень сообщений на значение num .

Уровни сообщений:

pcount - получить число параметров

Синтаксис:

pcount()

Результат: возвращает число параметров переданное процедуре. Можно использовать для контроля параметров переданных процедуре.

ping - выполнить ping

Синтаксис:

ping(ip,[len[,wait]])

Выполняет ping по заданному ip адресу. len длина пакета (до 1024). wait - время ожидания подтверждения в милисекундах.

Результат: если больше или равно 0 - то время ответа, если меньше 0, смотрите код ошибки lastrc()

ptype - получить тип параметра

Синтаксис:

ptype(pnum)

Результат: возвращает тип параметра pnum (нумерация с 0). Если '1' - то параметр типа указатель, и изменение этого параметра изменит переменную в вызывающей процедуре.

sleep - организовать задержку

Синтаксис:

sleep(nms)

Выполняет задержку в nms миллисекунд.

Результат: нет. Вызывайте функцию командой call

srvname - получить имя сервера

Синтаксис:

srvname()

Результат: Возвращает ip-адрес сервера, к которому сейчас выполнено подключение.

srvver - получить версию сервера

Синтаксис:

srvver()

Результат: Возвращает версию дистрибутива brgroute на котором собран сервер, если 0 - то сервер не на базе дистрибутива brgroute.

varexist - проверить что переменная существует

Проверяет существует переменная с заданным именем или нет и возвращает ее тип. Синтаксис:

varexist(varname[,vartype])

vartype - тип искомой переменной (1 - внешняя, 2 - глобальная)

Результат: "0" - переменная не существует, "1" - переменная существует

ver  - получить версию программы

Синтаксис:

ver()

Результат: возвращает версию программы iplnmng.

Написание своих функций на Си, оператор use

Если нужно ускорить какой либо кусок скрипта и его можно выделить как функцию, или требуется какая-либо новая операция, то имеется возможность написать ее на Си. Пример написания представлен в директории userlib

Внутренние функции имеют следующий формат вызова:

typedef int (*PINTFUNC)(PTSLOT pts, PSCRIPT pscr, char *pbuf, PCALLPARM pcp);

pts - хэндл задачи, нельзя трогать
pscr - хэндл скрипта, доступно поле lastrc
pbuf - указатель на буфер - куда записать значение функции
pcp - указатель на структуру передаваемых параметров.

Если функция возвращает значение отличное от 0, выполнение скрипта прекращается (считается что произошла фатальная ошибка). Если нужно передать код возврата, который может быть получен функцией lastrc, его нужно поместить в pscr->lastrc.

Переменные описываются следующей структурой:

typedef struct _var
{
    PVAR next;        // указатель на след. переменную (нельзя трогать)
    short type;         // тип переменной
    short namelen;  // длина имени переменной
    short asize;       // размер массива
    short aindex;    // индекс в массиве
    char name[MAX_VAR_NAME_LEN]; //имя переменной
    int vallen;        // длина значения переменной
    int valint;        // десятичное значение переменной
    union 
    {
        char sval[MAX_VAR_VAL_LEN]; //символьное значение переменной
    } d;
} VAR, *PVAR;

Если тип параметра описан как 'i' или 'u', то перед вызовом заполняется значение valint, иначе это поле не определено. Параметры в функцию передаются через структуру:

typedef struct _callparm
{
    int nparm;                                             //число параметров
    int types[MAX_SCRIPT_PARAM];     //тип параметров (1-указатель,0-локальная)
    PVAR pvars[MAX_SCRIPT_PARAM]; //указатель на переменную
    VAR tvar[MAX_SCRIPT_PARAM];     //массив локальных переменных
} CALLPARM, *PCALLPARM;

Обращаться к параметрам надо через массив pvars.

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

Для подключения библиотеки нужно скопировать ее в директорию scripts\dll, а в скрипте использовать команду:

use user_lib_name

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

Если в библиотеке, есть функции совпадающие с именем стандартных функций, то они замещают стандартные функции. Аналогично библиотека подключенная позднее, замещает аналогичные имена библиотеки подключенной ранее.

--------------------------------------------
Перейти в оглавление документации