MikroTik. Основы написания скриптов

Это основы написания скриптов для роутеров MikroTik. Функционал их достаточно велик, но его можно расширить с помощью написания скриптов.

Документация и примеры

Описание синтаксиса и примеров вы можете смотреть на следующих страницах:

Хранилище скриптов

В RouterOS есть специальное хранилище для скриптов — /system/script.

RouterOS - /system/script
RouterOS — /system/script

Хоть и возможно писать скрипты в окошке «Source«, но это совсем не удобно. А удобно для редактирования скриптов использовать терминал.

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

/system script add name=<имя скрипта>

А для его редактирования нужно использовать следующую команду:

/system script edit <имя скрипта> source

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

RouterOS - пример скрипта

Чтобы сохранить скрипт и закрыть редактор используйте комбинацию клавиш Ctrl+O, а чтобы закрыть редактор без сохранения Ctrl+C.

Недостатком такого метода является то, что при написании скрипта не подсвечивается синтаксис. Он начинает подсвечиваться только после сохранения скрипта (Ctrl+O) и последующего его открытия (/system/script/ edit <имя скрипта> source). При этом новые строки остаются не подсвечиваемыми до нового сохранения скрипта. Это означает что после каждой правки вам придется сохранять и пере-открывать скрипт, чтобы убедиться что нет синтаксических ошибок.

Например предыдущий скрипт после сохранения и последующего открытия выглядит таким образом:

RouterOS - пример скрипта

А чтобы запустить наш скрипт нужно использовать следующую команду:

/system script run <имя скрипта> 

Например:

RouterOS - запуск скрипта

Автоматическое выполнение скриптов

На практике часто требуется выполнять скрипты автоматически в зависимости от каких-либо событий.

Часто скрипты выполняются планировщиком заданий — /system/scheduler.

RouterOS — /System/scheduler

В поле «Interval» вы должны ввести интервал повторений, в моём случает интервал равен 30 секундам. А в поле «On Event» пишется скрипт, или можно вызывать скрипт из хранилища, как сделано у меня.

Скрипты могут срабатывать не только по определённому интервалу. Ещё они могут выполняться при наступлении определённых событиях:

  • /tool/trafic/monitor — при превышении трафика, или наоборот при слишком низком трафике на каком-либо интерфейсе;
  • /tool/netwatch — при доступности или недоступности узла сети;
  • /ppp/profile — при подключении или отключении vpn-клиентов;
  • /ip/hotspot/user/profile — при подключении или отключении hotspot клиента;
  • /system/reset-configuration/run-after-reset — выполнить скрипт после сброса роутера.

Скрипт можно писать либо напрямую в описанных выше пунктах меню, либо вызывать его из хранилища.

Синтаксис

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

Написание команд

Команды в RouterOS строятся из следующих элементов:

  1. Путь к объекту;
  2. Команда;
  3. Параметры команды без значений;
  4. Параметры команды со значениями.

Вначале мы указываем путь к объекту, например ip адреса у нас находятся в /ip/address/.

RouterOS - /ip/addresses
RouterOS — /ip/addresses

Путь до объектов в нашем случае будет таким: /ip addresses. Вначале ставим слеш «/«, а затем между узлами пути ставятся пробелы.

Затем пишем команду, вот примеры возможных команд:

  • print — выведет нам список уже созданных объектов (например ip адресов);
  • add — позволяет сделать новый объект (например добавить ip адрес);
  • remove — используется для удаления объекта;
  • disable — используется для выключения объекта;
  • get — получить свойства объекта;
  • есть и другие команды, которые мы разберём позже.

После команды можем написать её параметры, причем вначале нужно использовать параметры без значений, а потом параметры со значениями. Например при добавлении IP-адреса в качестве параметров можно использовать адрес и интерфейс.

Вот некоторые примеры:

/ip address print
Flags: X - disabled, I - invalid, D - dynamic 
 #   ADDRESS            NETWORK         INTERFACE                                                                 
 0   192.168.10.1/24    192.168.10.0    bridge-lan                                                                
 1 D 172.24.101.252/32  5.187.73.6      justlan                                                                   
 2 D 10.10.0.2/32       10.10.0.1       sstp-out-k

/ip address print where address="192.168.10.1/24"
Flags: X - disabled, I - invalid, D - dynamic 
 #   ADDRESS            NETWORK         INTERFACE                                                                 
 0   192.168.10.1/24    192.168.10.0    bridge-lan

/ip address add address=192.168.5.1/24 interface=bridge-lan 
/ip address print                                          
Flags: X - disabled, I - invalid, D - dynamic 
 #   ADDRESS            NETWORK         INTERFACE                                                                 
 0   192.168.10.1/24    192.168.10.0    bridge-lan                                                                
 1 D 172.24.101.252/32  5.187.73.6      justlan                                                                   
 2 D 10.10.0.2/32       10.10.0.1       sstp-out-k                                                                
 3   192.168.5.1/24     192.168.5.0     bridge-lan

/ip address remove numbers=3
/ip address print
Flags: X - disabled, I - invalid, D - dynamic 
 #   ADDRESS            NETWORK         INTERFACE                                                                 
 0   192.168.10.1/24    192.168.10.0    bridge-lan                                                                
 1 D 172.24.101.252/32  5.187.73.6      justlan                                                                   
 2 D 10.10.0.2/32       10.10.0.1       sstp-out-k

Некоторые команды можно использовать без пути, такие как:

  • :local — создание локальной переменной;
  • :global — создание глобальной переменной;
  • :set — присвоить значение переменной;
  • :put — вывод в консоль;
  • :log — запись в журнал;
  • :delay — задержка.

Все они, как вы могли заметить, начинаются на двоеточие. Эти команды на примерах рассмотрим ниже!

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

Переменные

Можно использовать локальные и глобальные переменные. Локальные видны в пределах скрипта, а глобальные можно использовать разными скриптами. При объявлении глобальной переменной, она сохраняется в память роутера до перезагрузки.

Локальную или глобальную переменную можно создать таким образом:

:local myVar;
:global myVar;

Для того чтобы назначить переменной значение используется команда :set:

:set myVar "Hello World!";

А чтобы вывести значение переменной на терминал нужно использовать :put и название переменной. Но перед названием переменной нужно поставить знак «$»:

:put $myVar;

Вот пример однострочного скрипта:

:local myVar; :set myVar "Hello World!"; :put $myVar;
Hello World!

А ещё переменным можно присваивать значения сразу при объявлении.

:local myIP 192.168.1.1;

Массивы

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

С помощью команды :len можно узнать размер массива, а с помощью :pick вывести определённый элемент массива.

:local m (192.168.5.10, 192.168.5.15, 192.168.5.25);
:put [:len $m];
:put [:pick $m 0];

Кстати в этих примерах используется ещё один приём. Когда мы хотим внутри одной команды выполнить другую, то мы используем квадратные скобки. Так в нашем примере, результат одной команды «:len $m» будет выведен в терминал с помощью команды «:put«.

Задержка

Иногда после выполнения команды нужно подождать несколько секунд, а затем продолжить выполнять следующие команды. В этом случае применяется команда :delay <количество секунд>, например:

:local myVar; :set myVar "Hello World!"; :delay 10; :put $myVar;
Hello World!

При выполнении этого скрипта терминал подождет 10 секунд, а затем на нём появится строка «Hello World!».

Запись в журнал

Команда «:log» позволяет вам сохранить какую-нибудь запись в журнал (Log). Она используется таким образом — :log <тема> <сообщение>. Например так:

:log info "Hello!"

В логах, после выполнения этой команды, появится запись «Hello!» в теме «script, info«.

Результат выполнения команды заносим в переменную

Мы уже встречались с приёмом, когда одну команду нужно выполнить внутри другой команды. А в этом примере я покажу как используя этот приём занести результат выполнения одной команды в переменную. Это делается следующим образом: :set $<переменная> «$[<команда>]». То-есть результат команды будет занесен в переменную. А вот пример такого скрипта:

:local myVar; :set $myVar "$[/system identity get name]"; :put $myVar;
MikroTik

В примере выше результат выполнения команды «/system identity get name» будет помещён в переменную «myVar«. А после чего, с помощью команды :put, я вывожу значение переменной в терминал.

Получение свойств объекта

В предыдущем примере используется команда get. Она необходима, чтобы получить свойства объекта.

/system identity get name

По пути /system/identity можно указать имя вашего роутера. А с помощью команды «get» мы это имя получаем. То-есть с помощью пути /system identity мы перешли к объекту в котором хранится имя роутера, затем с помощью get мы получаем свойства этого объекта. Но все свойства нам не нужны, поэтому мы используем параметр name, чтобы получить именно имя роутера.

Циклы, блоки команд и условный оператор if

Можно использовать следующие циклы и условные операторы в RouterOS:

  • :while (<условие>) do={<команды>}
  • :do {<команды>} :while=(<условие>)
  • :for <var> from=<int> to=<int> step=<int> do={<команды>}
  • :foreach <var> in=<array> do={<commands>}
  • :if(<условие>) do={<команды>} else={<команды>}

Вот пример работы условного оператора :if:

{
   :local myBool true;
   :if ($myBool = false) do={ :put "value is false" } else={ :put "value is true" }
}

Кстати, блок команд можно брать в фигурные скобки, как показано выше. Это можно применять прям в терминале для составления одной команды (не скрипта). То есть Вы открываете скобку и начинаете записывать ваш скрипт, после чего вы закрываете скобку, нажимаете Enter и скрипт выполняется.

Обработка ошибок

Если какая-то команда может завершиться с ошибкой и это не должно привести к прекращению работы скрипта. Тогда нужно ошибки обрабатывать. Делается это с помощью do {<блок команд>} on-error={<другой блок команд>}. Например так:

do {:put [:resolve test.ru]} on-error={:put "resolver failed"};
resolver failed

Здесь же продемонстрирован и пример одной команды внутри другой с помощью квадратных скобок. То есть выполняется команда :resolve test.ru, а её результат выводится в терминал с помощью :put. Но если :resolve test.ru завершиться ошибкой, то выполнится блок команд после on-error. И так как test.ru у меня не резолвится, то выполнилась команда :put «resolver failed».


Обратная связь

Я совсем немного пишу скрипты для роутеров MikroTik, и редко использую терминал, предпочитая ему WinBox. Поэтому если Вы в статье найдёте ошибки или неточности, то напишите в комментариях. И я поправлю или дополню эту статью.

Другие статьи посвященные MikroTik доступны здесь.

Если понравилась статья, подпишись на мой канал в VK или Telegram.

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять
Отказаться
Политика конфиденциальности