Дослідження змінних Mikrotik

Що ж нам каже Manual: Scripting про змінні у скриптах? А каже він нам, що змінні бувають двох областей видимості: локальні та глобальні, що оголошуються вони командами.

: local і: global

Пропоную відразу зосередитися на global змінних, тому що їх легше досліджувати за рахунок їхньої найкращої «спостереження», а більшість висновків, гадаю, можна спокійно перенести і на local.

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

Manual: Scripting говорить нам, що є близько десятка типів, з яких ми розглянемо лише деякі, важливі для розуміння змінних. Отже, явні та логічні типи: числовийnum, рядковийstr та масивarray. Далі згадується тип (воно ж значення змінної)nil, про який написано, що він буде у змінної за умовчанням, якщо їй нічого не присвоєно. Повіримо.

Якщо попрацювати з командною консоллю у WinBox, можна помітити, що є ще одне дивне ключове словоnothing, яке незрозуміло що означає якесь «нічого».

Ну і де тут nil? Проте повноnothing. Загалом, щоб розібратися з цими особливими типами та значеннями, застосуємо системний підхід, проаналізуємо видачу однотипних запитів, але з різними наборами вихідних даних. А вихідними даними у нас будуть на початку різні «дивні» константи та вирази. В результаті виходить така таблиця:

Тут дано результати порівняння різних констант виразів та команд над константами між собою. Розуміння властивостей констант допоможе при написанні правих частин операторів порівняння.

Щодо полів таблиці. У мові скриптів Mikrotik квадратні дужки позначають вбудовування результату команди у загальний вираз, у загальному сенсі value!= [value], це важливо.

Рядок 1: усі варіанти запису поляvalue синонімічні! У майбутньому я пропоную використовувати лаконічне[]. Повторюся, що квадратні дужки позначають вбудовування результату команди у загальний вираз. Як бачите, це один із способів «генерації»nil не в чистому вигляді, а як результат порожньої команди в квадратних дужках, який якраз дорівнюєnil.

Рядок 2: Тут все просто. Порожній рядок цілком очевидна річ. Єдиний момент, що вона виявляється дорівнює масиву з нічого, але пропоную не звертати на це особливої ​​уваги. І не можна використовувати порожній рядок як команду квадратних дужках, це єдине місце, де термінал не проковтнув синтаксис за вихідними даними таблиці, логічно.

Рядок 3: Круглі дужки несуть у собі вираз, всередині можна також поміститиnothing, і результат від такого виразу теж будеnothing, по суті це майже чистийnothing. Видно, що тип результату виразу(: nothing) даєnothing, а тип від обгортки з командних дужок[] даєnil, по аналогії з рядком 1. Взагалі після повторного осмислення написаного, зрозумів що це спекуляція, т.к. всередину() можна помістити будь-що, будь-який безглуздий набір символів, головне, що результат(…) даєnothing.

Рядок 4: Масив, який містить нічого, насправді містить один елемент. Тип, як і очікувалося,array, тип результату командної обгортки також даєnil

Рядок 5: Добираємося до елемента масиву з нічого, простежується повна аналогія видачі з рядком 3. Загалом такийелемент - це також чистеnothing.

Які загальні висновки можна зробити з цього дивного brainfuck-а.nothing дійсно існує, ним можна оперувати, рідкісні висловлювання можуть його повертати, але команди в[] ніколи не повертаютьnothing, а тількиnil. Інший більш важливий висновок, що оператор довжини значення або кількість елементів масиву: len поводиться дуже стабільно і генерує передбачуваний результат, тому його я можу однозначно рекомендувати для використання в скриптах, коли потрібна перевірка повертаються виразами і командами значень. І що[] = [: nothing] = nil.

Таблиця дає уявлення про те, що можуть повертати різні команди та вирази мови Mikrotik.

н./і. - не використовується; н./п. - не застосовується

1. Змінну створено, але їй нічого не присвоєно. Змінна міститьnothing. 2. Якщо змінної привласнити такий вираз, це призведе до видалення глобальної змінної зі змінних оточення. 3. Стандартний спосіб створення пустих змінних. Змінна міститьnil. 4. Присвоєння порожнього рядка. Тут усе очевидно. 5. Виходить, що такий вираз аналогічний[] простому присвоєннюnil, як у 3. Думаю, це тому, що всередині[] неіснуюча команда і результат цієї команди даєnil 6, 7, 8. Присвоєння фігурних дужок робить із змінної масив, хоч і порожній. Зауважте, що записи мають однакові результати в таблиці, але це не стосується властивостей елементів цих масивів. Властивості елементів масивів розглянуті нижче. 4, 9, 10. Прості типи даних. Все досить очевидно. 11. Масив з одного елемента, зверніть увагу, що за результатами дорівнює 12, 13, 14. У масив можуть входити елементи різних типів даних.Дослідження властивостей елементів масиву дає передбачувані результати. 15, 16, 17. Один із елементів масивуnothing. Елементи масиву мають ті ж властивості, що і просто змінні і константи даних типів і значень. Простежується аналогія із пунктом 2. 18, 19. Простежується аналогія із пунктом 3.

Дослідження, на мій погляд, вийшло трохи спірним, але я дуже сподіваюся, воно внесе більше порядку у ваше розуміння Mikrotik ніж хаосу. Як додаткову компенсацію публікую скрипт для роботи з динамічним DNS чудового сервісу FreeDNS.afraid.org.

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

Оголошуємо допоміжні змінні:

Масив лічильників дозволить оновлювати Dynamic DNS записи незалежно один від одного.

Наступні конструкції працюють для щойно створених змінних, перевіряється тип даних, якщо він не масив, то тип змінюється на масив, і надаються значення змінних. Таким чином, на виході ми маємо проініціалізовані потрібними значеннями змінні типу масив.

Не й сам алгоритм відстеження-оновлення.

Як я писав вище, найбільшу стійкість має оператор : len, тому використовуємо його далі для перевірки адекватності отриманих даних[: len $CurrentIP] > 0. Ще відстежуємо значення лічильника, і якщо він >=60, примусово надсилаємо запит у FreeDNS. Таким чином, підвищується стійкість алгоритму до проблем зв'язку. Скрипт у шедулері у мене виконується раз на хвилину, тому період обов'язкового оновлення близько 1 години, що не обтяжує сервіс FreeDNS.