Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • Changelogs
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    RouterOS
    Функции в CMD-скриптах

    Функции в CMD-скриптах

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Функции в CMD-скриптах, RouterOS
     
    dssmiktik
    Guest
    #1
    0
    26.01.2010 22:55:00
    Вот скрипт, который оказался для меня полезным, надеюсь, и другим он пригодится. Я уже несколько лет пользуюсь Mikrotik и заметил, что часто использую один и тот же код. Скрипты Mikrotik CMD не поддерживают функции, которые можно вызывать из других скриптов, поэтому я решил придумать простой способ это обойти. Публикую здесь, чтобы получить ваши комментарии, предложения и отзывы по этому коду. Если все недочеты будут устранены, надеюсь, что и другие смогут добавить свои функции. Важно: Lua умеет работать с функциями внутри скриптов, но она не реализована в RouterOS версии v2.x, v3.30 и v4.5. Также можно использовать несколько скриптов с глобальными переменными для передачи данных между ними, но это требует, чтобы никакой другой скрипт не использовал те же глобальные переменные. Благодаря «внедрению» глобальных переменных в функции, функции становятся более гибкими и уменьшается вероятность конфликтов глобальных переменных. Итак, сам скрипт:

    # Имя скрипта: Functions  
    # Библиотека функций  
    # Помните: символы '$' (доллар), '"' (двойные кавычки) и '\' (обратный слеш) внутри функций должны экранироваться обратным слешем '\'  
    # Входной массив функции передается из вызывающего скрипта так:  
    # строка: ":local input \"<input1,input2,...>\"; "  
    # результат команды: ":local input [/path/to/command get <item property>];"
    # Выходной массив функции сохраняется в локальной переменной $output  
    # Функции всегда должны заканчиваться ; (точкой с запятой) — так их удобнее вызывать из других скриптов  

    # Пример вызова функции MyFunc с входом "1,2,3,4" и сохранением результата в глобальную переменную MyOutput  
    # В вызывающем скрипте:  
    # Код  
    #    /system script run "Functions"  
    #    :global MyFunc  
    #  
    #    :global MyOutput ""  
    #    :local runFunc [:parse (":global MyOutput;" . \
    #    ":local input \"1,2,3,4\";" . \  
    #                 $MyFunc . \  
    #    ":set MyOutput \$output")  
    #   ]  
    #    $runFunc  
    # Конец кода  

    # Глобальная переменная $MyOutput теперь содержит массив с результатами функции  
    # Для вывода результата:  
    #    :put [:pick $MyOutput 0]
    #    :put [:pick $MyOutput 1]
    #    :put [:pick $MyOutput 2]
    #    :put [:pick $MyOutput ...]

    # Функции  
    #------------

    # RandomNumGen: Генерирует достаточно случайное число на основе даты, времени, свободной памяти и загрузки CPU  
    # Входной массив: отсутствует  
    # Выходной массив:  
    # 0 = сгенерированное число  
    :global RandomNumGen ":local output \"\"  
    :set output (\$output . [:pick [/system clock get date] 7 11])
    :set output (\$output . [:pick [/system clock get date] 4 6])
    :set output (\$output . [:pick [/system clock get time] 0 2])
    :set output (\$output . [:pick [/system clock get time] 3 5])
    :set output (\$output . [:pick [/system clock get time] 6 8])
    :set output (\$output . [/system resource get free-memory])
    :set output (\$output . [/system resource get cpu-load])
    :set output [:tonum \$output]
    :set output [:toarray \$output];"

    # DateToNum: Преобразует дату в формате "mmm/dd/yyyy" в числовой формат "yyyymmdd"  
    # Входной массив:  
    # 0 = строка даты "mmm/dd/yyyy"  
    # Выходной массив:  
    # 0 = числовая дата yyyymmdd  
    :global DateToNum " :local output \"\"  
    :set input [:toarray \$input]
    :if ([:len \$input] > 0) do={
    :local input1 [:tostr [:pick \$input 0]]
    :local months [:toarray \"jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec\"]
    :local mon 0  
    :for x from=0 to=([:len \$months] - 1) do={
      :if ([:tostr [:pick \$months \$x]] = [:tostr [:pick \$input1 0 3]]) do={
         :if (\$x < 9) do={ :set mon (\"0\" . (\$x + 1)) } else={ :set mon (\$x + 1) } } }  
    :set output ([:pick \$input1 7 11] . \$mon . [:pick \$input1 4 6])
    :set output [:tonum \$output]
    :set output [:toarray \$output]
    };"

    # TimeToNum: Убирает двоеточия из строки времени "hh:mm:ss" -> "hhmmss"  
    # Входной массив:  
    # 0 = строка времени "hh:mm:ss"  
    # Выходной массив:  
    # 0 = числовое время hhmmss  
    :global TimeToNum " :local output \"\"  
    :set input [:toarray \$input]
    :if ([:len \$input] > 0) do={
    :local input1 [:tostr [:pick \$input 0]]
    :for x from=0 to=([:len \$input1] - 1) do={
      :if ([:tostr [:pick \$input1 \$x (\$x + 1)]] != \":\") do={
         :set output (\$output . [:tostr [:pick \$input1 \$x (\$x + 1)]]) } }
    :set output [:tonum \$output]
    :set output [:toarray \$output]
    };"

    # RegExFind: Ищет точное соответствие регулярному выражению в строке  
    # Входной массив:  
    # 0 = строка для поиска  
    # 1 = шаблон регулярного выражения  
    # Выходной массив:  
    # 0 = индекс начала совпадения (-1, если не найдено)  
    # 1 = индекс конца совпадения (-1, если не найдено)  
    :global RegExFind " :local output \"\"  
    :set input [:toarray \$input]
    :if ([:len \$input] > 1) do={
    :local input1 [:tostr [:pick \$input 0]]
    :local input2 [:tostr [:pick \$input 1]]
    :for x from=0 to=([:len \$input1] - 1) do={
      :if ([:pick \$input1 \$x [:len \$input1]] ~ (\"^\" . \$input2)) do={
         :for y from=\$x to=([:len \$input1] - 1) do={
            :if ([:pick \$input1 \$x (\$y + 1)] ~ (\$input2 . \"\\\$\")) do={
               :set output (\$x . \",\" . \$y) } } } }  
    :if ([:len \$output] = 0) do={ :set output \"-1,-1\" }
    :set output [:toarray \$output]
    };"

    # -----------------  
    # Конец библиотеки функций

    # Скрипт-пример использования функций  # Имя скрипта: DemoFunctions  
    # Демонстрация библиотеки функций

    # Импорт скрипта Functions и используемых функций  
    /system script run "Functions"  
    :global RandomNumGen  
    :global DateToNum  
    :global TimeToNum

    # Демонстрация RandomNumGen  
    :global DemoRandomNum 0  
    :local runFunc [:parse (":global DemoRandomNum;" . \
    $RandomNumGen . \  
    ":set DemoRandomNum \$output")  
    ]  
    $runFunc  
    :put ("Случайное число: " . [:pick $DemoRandomNum 0])

    # Демонстрация DateToNum  
    :global DemoDate 0  
    :local runFunc [:parse (":global DemoDate;" . \
    ":local input [/system clock get date]; " . \
    $DateToNum . \  
    ":set DemoDate \$output")  
    ]  
    $runFunc  
    :put ("Дата в числовом формате: " . [:pick $DemoDate 0])

    # Демонстрация TimeToNum  
    :global DemoTime 0  
    :local runFunc [:parse (":global DemoTime;" . \
    ":local input [/system clock get time]; " . \
    $TimeToNum . \  
    ":set DemoTime \$output")  
    ]  
    $runFunc  
    :put ("Время в числовом формате: " . [:pick $DemoTime 0])

    Снова, пожалуйста, оставляйте отзывы и предложения.
     
     
     
    dssmiktik
    Guest
    #2
    0
    16.02.2010 21:17:00
    Я не смогу запрограммировать функцию MD5 на CMD-скриптах — это слишком сложно и долго прямо сейчас. Пароли на устройствах Mikrotik не устанавливаются с использованием хэширования. Их можно задать напрямую, без хэширования. Думаю, что в RouterOS v5 Lua будет поддерживать MD5-хэширование, так что следите за обновлениями. Если вам действительно нужно захешировать пароль с помощью MD5, советую выполнить этот код на Linux-машине: ssh <user>@<router> ':put [/ppp secret get <user> password]' | md5sum
     
     
     
    dssmiktik
    Guest
    #3
    0
    19.05.2010 00:06:00
    Я разработал алгоритм хеширования MD5 для скрипта Mikrotik RouterOS. Пока что он работает с любыми данными, которые можно прочитать в RouterOS (файл, переменная, свойства [get] и т.д.). Алгоритм отлично работает и выдает точный результат, но я всё ещё занимаюсь оптимизацией и доработкой кода для использования в продакшене. Если вам интересно, я могу предоставить этот код за символическую плату (так как его создание требует много времени) через PayPal на адрес: dscomputer_2000[at]hotmail[dot]com. Также можете связаться со мной по этому же email для обсуждения деталей. Спасибо, Дуг.
     
     
     
    fewi
    Guest
    #4
    0
    19.05.2010 04:04:00
    Ты просто с ума сошёл, и я говорю это в самом лучшем смысле. MD5 в встроенном скриптовом языке — это чертовски крутой костыль.
     
     
     
    dssmiktik
    Guest
    #5
    0
    19.05.2010 04:48:00
    fewi, да, это был настоящий вызов. В последнее время я участвовал в нескольких проектах, где понадобилась функция хеширования MD5 (без внешних зависимостей), и понял, что на этом форуме тоже есть такая потребность. Здесь используется метод из этого поста по созданию функций с помощью скриптов RouterOS. Всё это работает и с большими файлами (например, файл 8 КБ, разбитый на два по 4 КБ, считанный через [/file get xxx contents]), при этом генерируется тот же хеш, что и функция md5sum в Linux для одного файла в 8 КБ. Кстати, если кому-то нужен продвинутый скриптинг, я на связи (мой email указан выше).
     
     
     
    markmcn
    Guest
    #6
    0
    26.07.2010 15:46:00
    dssmiktik, просто интересно, за сколько ты продаёшь копии этого скрипта для подсчёта md5?
     
     
     
    dssmiktik
    Guest
    #7
    0
    29.07.2010 21:42:00
    Подробности о том, как получить скрипт, можно узнать здесь.
     
     
     
    dssmiktik
    Guest
    #8
    0
    02.08.2010 18:51:00
    Также не стесняйтесь писать мне по любым вопросам на электронную почту: dscomputer_2000[собака]hotmail[точка]com
     
     
     
    dssmiktik
    Guest
    #9
    0
    05.10.2010 04:49:00
    markmcn & bluestar, дайте знать, если вы всё ещё заинтересованы в скрипте MD5 или чем я могу помочь. С наилучшими пожеланиями,
     
     
     
    thegink
    Guest
    #10
    0
    12.10.2011 02:22:00
    Вот функция, которую я использую для приёма ввода от пользователя. Это расширение одного из скриптов dssmiktik, который можно найти здесь.

    # Название скрипта: Functions  
    # Библиотека функций  
    # Помните: символы ' $ ' (доллар), ' " ' (двойная кавычка) и ' \ ' (обратный слэш) должны быть экранированы предшествующим обратным слэшем '\' при использовании в функциях.  
    # Массив входных данных функции передаётся из вызывающего скрипта так:  
    #   строка:          ":local input \"<input1,input2,...>\"; "  
    #   вывод команды:   ":local input [/path/to/command get <item property>];"
    # Массив выходных данных функции хранится в локальной переменной $output функции  
    # Функции всегда должны заканчиваться на ; (точка с запятой) — это упрощает вызов из другого скрипта.  

    # Пример вызова MyFunc с входными данными "1,2,3,4" и сохранением результата работы в глобальную переменную MyOutput:  
    # В вызывающем скрипте:  
    # Код  
    #    /system script run "Functions"  
    #    :global MyFunc  
    #  
    #    :global MyOutput ""  
    #    :local runFunc [:parse (":global MyOutput;" . \
    #             ":local input \"1,2,3,4\";" . \  
    #                       $MyFunc . \  
    #             ":set MyOutput \$output")  
    #         ]  
    #    $runFunc  
    # Конец кода  
    #  
    # Теперь глобальная переменная $MyOutput содержит массив выходных значений функции  
    # Для вывода результата:  
    #    :put [:pick $MyOutput 0]
    #    :put [:pick $MyOutput 1]
    #    :put [:pick $MyOutput 2]
    #    :put [:pick $MyOutput ...]


    # Функции  
    #------------  


    # Prompt: Отображает приглашение в командной строке и принимает ввод от пользователя.  
    # Входной массив:  
    #   0 = сообщение приглашения  
    #   1 = отображать введённый текст (0 - по умолчанию) или скрывать (1)  
    # Выходной массив:  
    #   0 = введённые данные пользователя  
    :global Prompt ":local output \"\"  
               :set input [:toarray \$input]
               :if ([:len \$input] > 0) do={
                   :local input1 [:tostr [:pick \$input 0]]
                   :local echo 0  
                   :if ([:len \$input] > 1) do={
                       :set echo [:tonum [:pick \$input 1]]
                   }  
                   :local asciichar (\"0,1,2,3,4,5,6,7,8,9,\" . \  
                                     \"a,b,c,d,e,f,g,h,i,j,k,l,\" . \  
                                     \"m,n,o,p,q,r,s,t,u,v,w,x,y,z,\" . \  
                                     \"A,B,C,D,E,F,G,H,I,J,K,L,\" . \  
                                     \"M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,\" . \  
                                     \".,/\")  
                   :local asciival {48;49;50;51;52;53;54;55;56;57; \  
                                    97;98;99;100;101;102;103;104;105;106;107;108; \  
                                    109;110;111;112;113;114;115;116;117;118;119;120;121;122; \  
                                    65;66;67;68;69;70;71;72;73;74;75;76; \  
                                    77;78;79;80;81;82;83;84;85;86;87;88;89;90; \  
                                    46;47}  
                     
                   :local findindex;  
                   :local loop 1;  
                   :local key 0;  
                   :put \"\$input1\";  
                   :while (\$loop = 1) do={  
                       :set key ([:terminal inkey])
                       :if (\$key = 8) do={  
                           :set output [pick \$output 0 ([:len \$output] -1)];
                           :if (\$echo != 1) do={  
                               :put \"\r\$output              \";  
                               /terminal cuu 0;  
                           } else={  
                               :local stars;  
                               :if ([:len \$output] > 0) do={
                                   :for x from=0 to=([:len \$output]-1) do={
                                       :set stars (\$stars . \"*\");  
                                   }      
                               }  
                               :put \"\r\$stars                         \";  
                               /terminal cuu 0;  
                           }  
                       }  
                       :if (\$key = 13) do={  
                           :set loop 0;  
                           put \"\";  
                           } else={  
    #                       # Преобразование числового ASCII-кода в символ ASCII  
                           :set findindex [:find [:toarray \$asciival] \$key]
                           :if ([:len \$findindex] > 0) do={
                               :set key [:pick [:toarray \$asciichar] \$findindex]
                               :set output (\$output . \$key);  
                               :if (\$echo != 1) do={  
                                   :put \"\r\$output                \";  
                                   /terminal cuu 0;  
                               } else={  
                                   :local stars;  
                                   :for x from=0 to=([:len \$output]-1) do={
                                       :set stars (\$stars . \"*\");  
                                       }  
                                   :put \"\r\$stars                     \";  
                                   /terminal cuu 0;  
                               }  
                           }  
                       }  
                   }  
                   :set output [:toarray \$output]
               };"  
                   


    # -----------------  
    # Конец функций. Вот несколько примеров их использования:  
    :global Prompt;  
    :local runFunc;  
    /system script run Functions  

    # Запрос IP-адреса  
       :local ipaddress;  
       :set runFunc [:parse (":global ipaddress;" . \
            ":local input \"Введите IP-адрес или оставьте пустым, чтобы пропустить:\";" . \  
                      $Prompt . \  
            ":set ipaddress \$output")  
        ]  
       :do { $runFunc } while=([:len [:toip value=$ipaddress]] = 0 && [:len $ipaddress] > 0);

    # Запрос пароля — ввод скрывается звёздочками  
       :local password;  
       :set runFunc [:parse (":global password;" . \
                ":local input \"Введите пароль системы или оставьте пустым, чтобы пропустить:,1\";" . \  
                          $Prompt . \  
                ":set password \$output")  
            ]  
       $runFunc;  
       if ([:len $password] > 0) do={ /user set admin password=$password }

    Спасибо за проделанную работу, Doug!
     
     
     
    samuel345
    Guest
    #11
    0
    08.01.2013 08:38:00
    Я пытался сделать этот скрипт последние пару недель, но постоянно появлялись ошибки. Спасибо за этот пост — он помог мне разобраться с ошибкой в скрипте. Проблемы с принтером
     
     
     
    HaPe
    Guest
    #12
    0
    24.05.2013 17:16:00
    Привет! Есть ли в скриптах Mikrotik что-то аналогичное функции read (например, из bash)?
     
     
     
    JAza
    Guest
    #13
    0
    09.07.2015 23:40:00
    Это всё ещё актуально для ROS версии 6 или даже 5? Или сейчас есть более «родной» способ передавать параметры, вызывать функции/процедуры или даже другие скрипты? Спасибо.
     
     
     
    mrz
    Guest
    #14
    0
    10.07.2015 07:53:00
    http://wiki.mikrotik.com/wiki/Manual:Scripting#Functions
     
     
     
    bluestar
    Guest
    #15
    0
    13.02.2010 10:14:00
    Все наши логины динамически меняются через случайные интервалы. У нас корректно настроен радиус-сервер в продакшене. Наши клиенты с роутерами Mikrotik, которые используют аутентификацию L2TP-туннелей к центральному офису, также нуждаются в автоматической и периодической смене пароля для аутентификации. Чтобы эта функция работала, нам нужен md5, который сможет генерировать хэш для следующих частей скриптов.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2025 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры