Функции в скриптах Микротик

Здесь выкладываем скрипты
Ответить
Sertik
Сообщения: 622
Зарегистрирован: 15 сен 2017, 09:03

29 сен 2017, 10:15

Итак разобрался сам с функциями в скриптах Микротик. Может кому пригодиться.

Чтобы сделать функцию сначала пишем ее:

:global myFunc do={сама функция. Если в ней используются глобальные переменные, то здесь до их упоминания нужно их снова объявить вот так :global Var.
Если Вы передаете параметры в функцию, то их объявлять не надо. В том числе ни коем случае их имена не должны совпадать с именами глобальных переменных, иначе они будут проигнорированы. Если из функции нужно вернуть значения чего то, то делаем это в теле функции так :local Vanswer; :set Vanswer Lala; :return $Vanswer}

При исполнении вышеизложенного, если все правильно, проверяйте в окружении появится глобальная переменная myFunc - это и есть наша функция.
Чтобы ее вызвать, например из другого скрипта, нужно опять сначала ее обязательно объявить в этом скрипте:
:global myFunc;

Чтобы выполнить ее делаем просто так (Var - имя передаваемого параметра, их может быть сколько-угодно):
$myFunc Var=Lala; #Lala может быть значением или переменной

Чтобы из нее вернулся ответ от Vanswer вызываем ее например, так:
:local Vanswer [$myFunc Var=Lala];

Все реально работает. Хорошо все демонстрирует библиотека функций Edelveys из Aleksov` blog. Там все рабочее.
Только там нет примеров возврата значений из функции. С этим разобрался сам.

Только не разобрался могут ли функции Микротик возвращать несколько параметров. Может кто знает ?


Чего не знаем то нагуглим
Аватара пользователя
podarok66
Модератор
Сообщения: 3228
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

29 сен 2017, 11:22

Sertik писал(а):Все реально работает. Хорошо все демонстрирует библиотека функций Edelveys из Aleksov` blog. Там все рабочее.
Только там нет примеров возврата значений из функции. С этим разобрался сам.

Ссылочку на библиотеку приложили бы, что ли.
И реально работающий пример, с возвратом функций, чтобы начинающие не только теорию, но и практический аспект видели.
Sertik писал(а):Чтобы выполнить ее делаем просто так (Var - имя передаваемого параметра, их может быть сколько-угодно):
$myFunc Var=Lala; #Lala может быть значением или переменной

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


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 622
Зарегистрирован: 15 сен 2017, 09:03

29 сен 2017, 11:46

Недавно написал несколько функций обеспечивающих доступ напрямую с Микротика к устройствам Нетпинг компании "Алентис-Электроникс" (www.netping.ru). Выложить их пока не могу, т.к. обещал сначала передать компании.
Вообще функции понравились, реально работают в ROS. Планирую написать функции для работы с Poe-портами, чтобы включать/выключать, опрашивать значения напряжения/тока/мощности на включенном порту.
Как будут готовы и проверены ценные примеры - выложу.


Чего не знаем то нагуглим
Sertik
Сообщения: 622
Зарегистрирован: 15 сен 2017, 09:03

29 сен 2017, 11:49

А вот ссылочка на библиотеку функций от Aleksov`s blog:

https://blog.set-pro.net/%d0%b1%d0%b8%d ... -routeros/


Чего не знаем то нагуглим
Sertik
Сообщения: 622
Зарегистрирован: 15 сен 2017, 09:03

29 сен 2017, 15:39

Для демонстрации примера возврата результата из функции могу подарить сообществу функцию FuncActIface.

Функция проверяет наличие активного шлюза в Интернет (с нулевым маршрутом) и возвращает в качестве своего результата имя интерфейса этого шлюза

Итак сама функция:

:global FuncActIface do={
# Get address active gateway - in var $activeGateway
/ip route
{ :local counter;
:foreach counter in=[find dst-address=0.0.0.0/0] do={
:if ([get $counter active] = true) do={
:set $activeGateway [get $counter gateway];
} }}
:if ($activeGateway!=nil) do={
# Get Gateway with gateway-status active
:local GatewayStatus;
:set $GatewayStatus [ :tostr [ /ip route get [ find gateway=$activeGateway dst-address=0.0.0.0/0 ] gateway-status ]];
#:log info $GatewayStatus;

# Seek Interface name in $GatewayStatus (after "via" verb)
:local activeInterface;
:set $activeInterface [ :pick $GatewayStatus ( [ :len [ :pick $GatewayStatus 0 [ :find $GatewayStatus "via" ] ] ] + 5 ) [ :len $GatewayStatus ] ];

:return $activeInterface;
} else={:local activeInterface "not found"; :return $activeInterface;}
}

Пример ее вызова с печатью имени интерфейса с активным маршрутом в Интернет в лог:

:global FuncActIface;
:log info [$FuncActIface]


Чего не знаем то нагуглим
Аватара пользователя
podarok66
Модератор
Сообщения: 3228
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

29 сен 2017, 20:41

Да, огромное спасибо и за ссылки и за пример. Признаюсь откровенно, это в моём понимании весьма серьёзный уровень. Я так не умею. Это не вам надо тут спрашивать, а нам у вас, что и как написать :smu:sche_nie:
Правда у меня возврат при ваших данных выводит

Код: Выделить всё

0.201.10.254 ether4

Если поменять +5 на +4 то выводит как надо

Код: Выделить всё

10.201.10.254 ether4

Впрочем, у меня два активных интерфейса :-) и маршрут не нулевой.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 622
Зарегистрирован: 15 сен 2017, 09:03

02 окт 2017, 20:58

Да, эта функция конечно, к сожалению, не универсальна. Она приведена только для примера. К сожалению в Роутер Ос на запрос
[ /ip route get [ find gateway=$activeGateway dst-address=0.0.0.0/0 ] gateway-status ]] можно получить все что угодно. Например для ethernet-интерфейсов одно, для lte интерейсов вообще другое. Да, и прошу простить за некорректные высказывания ...
Уровень у меня так себе. Раньше серьезно увлекался системным программированием (это было больше 25 лет назад на ПК Apple II точнее ПЭВМ Агат-9). Тогда я кое-чего добился и кое-что в голове видимо осталось. Но я самоучка всего-лишь, а были люди и покруче весьма ...

Вот Вам еще простенькая функция-пример:

# Функция проверки напряжения на Poe-порту;
# Если питание включено - возвращает в переменной Rvoltage напряжение в строковом виде
# Если питание Poe-порта выключено - возвращает строку "Poe off"

# Если порта с указанным номером нет (или указано порт не имеющий Poe), или параметр задан не корректно - просто виснет.
# Вот это обидно. Нужно вставить обработку ошибок. Может кто знает как и допишет ?

:global FuncPoe do={:local Pstatus; :local Rvoltage;
/interface ethernet poe monitor ("ether"."$EPort") once do={:set Pstatus $"poe-out-status"};
:if ($Pstatus="powered-on") do={ /interface ethernet poe monitor ("ether"."$EPort") once do={:set Rvoltage ([:pick $"poe-out-voltage" 0 2] . "." . [:pick $"poe-out-voltage" 2 3])};
:return $Rvoltage;} else={:set $Rvoltage "Poe off"; :return $Rvoltage}
}}

Вызывать функцию надо так:

:global FuncPoe;
:log info [$FuncPoe EPort="2"]; # В EPort указывайте реально существующий в модели Вашего роутера Poe-port.


Чего не знаем то нагуглим
Ответить