Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • 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
    elif statement

    elif statement

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    elif statement, RouterOS
     
    vasilaos
    Guest
    #1
    0
    08.10.2014 08:52:00
    Можно ли использовать оператор elif в скриптах Mikrotik?
     
     
     
    Jotne
    Guest
    #2
    0
    06.09.2019 05:03:00
    Так ты над этим работаешь? Я жду с большим энтузиазмом.
     
     
     
    SiB
    Guest
    #3
    0
    06.09.2019 07:31:00
    WorkARound, намного лучше, чем if else if else…  
    local myFunc do={put $1}  
    if ($n=1) do={$MyFunc "A"}  
    if ($n=2) do={$MyFunc "B"}  
    if ($n=3) do={$MyFunc "C"}  
    if ($n!=1 & $n!=2 & $n!=3) do={$MyFunc "Other"}
     
     
     
    alna7ari
    Guest
    #4
    0
    09.11.2021 23:32:00
    Опоздал, но оставлю ответ для других, потому что не нашёл убедительного решения:

    :global counter 0  
    :global ifElseWorkAround do={  
     # if  
     if ($counter > 180) do={  
       # ваш код  
       :set counter ($counter+1)  
       :return null;  
     }  
     # elseif  
     if ($counter > 90) do={  
       # ваш код  
       :set counter ($counter+2)  
       :return null;  
     }  
     # elseif  
     if ($counter > 45) do={  
       # ваш код  
       :set counter ($counter+3)  
       :return null;  
     }  
     # Повторяйте блок elseif столько, сколько нужно  
     # В конце разместите код, который выполнится, если ни одно из условий не подошло  
     # else код здесь  
     :set counter ($counter+4)  
    };  
    $ifElseWorkAround;
     
     
     
    Deantwo
    Guest
    #5
    0
    12.11.2021 09:33:00
    Извиняю вас двоих, но как и почему любой из этих двух примеров кода должен работать как ELSE IF? Конечно, можно сделать список IF, который выглядит аккуратнее, наподобие SWITCH CASE, но это всё равно не то же самое и требует точного понимания, что ты делаешь. Красивого обходного пути тут нет. Лучшее, что можно сделать, это вот так:

    if ($b1) do={
       # если $b1, то это
    } else={
       if ($b2) do={
           # иначе, если $b2, то это
       } else={
           # иначе это
       }
    }

    Ты не сможешь сделать управление потоком красивым, если это сильно увеличит шанс сломать код.
     
     
     
    rextended
    Guest
    #6
    0
    12.11.2021 10:06:00
    Лучше вариант с @SiB, потому что можно изменить или уже изменённое тестируемое значение. Например, «elseif» или switch выполняются только один раз. (Ошибки в SiB исправлены, код валидный, добавлены другие, исправлено в 2023):

    :global n 2
    {
       :local MyFunc do={ :put $1; :set n 0 }
       :local MyFuncU do={ :put "Значение N вне диапазона (1-3) ($1)"; :set n 0 }
       :local switch true
       :if ($n=1 and $switch) do={ [$MyFunc "A"]; :set switch false }
       :if ($n=2 and $switch) do={ [$MyFunc "B"]; :set switch false }
       :if ($n=3 and $switch) do={ [$MyFunc "C"]; :set switch false }
       :if ($switch) do={ [$MyFuncU $n] }
    }

    ИЗМЕНЕНИЕ: исправлены синтаксические ошибки, которые ранее не заметили.
     
     
     
    Deantwo
    Guest
    #7
    0
    12.11.2021 13:19:00
    Наверное, твоё изменение решает проблему, которая была у меня с тем, что $n одновременно равен нескольким вариантам. Но всё равно складывается впечатление, что ты усложняешь простой IF ELSEIF ELSE больше, чем нужно. Обычному пользователю будет сложно просто скопировать и вставить твой пример кода и заставить его работать без ошибок. Принцип “Проще — лучше” (KISS) очень важен, если хочешь, чтобы твой код могли поддерживать другие. А давать сложные обходные решения новичкам тут кажется плохой идеей.
     
     
     
    rextended
    Guest
    #8
    0
    12.11.2021 13:44:00
    И да, хорошее замечание, и нет: просто так оно и работает, сравниваясь только один раз, потому что значение может измениться по разным причинам где-то в другом месте. Что-то вроде этого может помочь:

    […]
    :local switch true
    :local temporary-variable-that-store-the-value-readed-only-one-time $n
    :if ($temporary-variable-that-store-the-value-readed-only-one-time=1 && switch) do={
       $MyFunc “A”;
       :set $switch false
    }
    […]

    Это просто обходной путь, потому что elseif / switch / case / и т.д. пока не существуют…
     
     
     
    fragtion
    Guest
    #9
    0
    26.02.2023 13:04:00
    @rextended: Простите за возможное незнание с моей стороны, но разве не должно быть «&& $switch», а не просто «&& switch»? Что я упускаю? Пытаюсь сделать скрипт для автоматической настройки QoS для LTE, когда главная базовая станция уходит в офлайн, и мои скорости падают с примерно 50 Мбит/с до 1-2 Мбит/с. Нужно выжать максимум из такой маленькой пропускной способности… Вот где я сейчас:
    /system scheduler add interval=3s name=wan1-autoqos on-event="/system/script/run wan1-autoqos" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup

    /system/script/ name=wan1-autoqos
    :local spdmin 512
    :local spdmax 51200
    :local spdsafe 2500
    :local pingcount 3
    :local movingaverage 2

    :global wan1qos
    :global avgpacketloss
    :local curpacketloss
    :local adjamt 0
    :local spdadj
    :local lastqos $wan1qos

    #:log info ("")

    :if ([/interface/ethernet/get ether1_wan running]=true) do={
     :local count [/ping address="8.8.4.4" interface="ether1_wan" src-address="192.168.8.100" size=28 interval=1 count=$pingcount]
     #:local count 3
     :set curpacketloss (($pingcount - $count) * 100 / $pingcount)
     #:log info "Процент потерянных пакетов: $curpacketloss% (получено $count из $pingcount)"
     :set avgpacketloss (($avgpacketloss * ($movingaverage - 1) + $curpacketloss) / $movingaverage)
     #:log info "Средний процент потерь пакетов: $avgpacketloss"
     :local switch true
     :if (($avgpacketloss > 10) && ($curpacketloss > $avgpacketloss)) do={
       # Потеря пакетов — уменьшаем скорость
       :if ($wan1qos > 5000 && switch) do= { :set wan1qos $spdsafe; set $switch false }
       :if ($wan1qos > 4000 && switch) do= { :set adjamt 512; :set $switch false }
       :if ($wan1qos > 3000 && switch) do= { :set adjamt 128; :set $switch false }
       :if ($wan1qos > 0 && switch) do= { :set adjamt 64; :set $switch false }
       :set spdadj (-1 * $adjamt)
     } else {
       # Потерь нет или они снижаются — увеличиваем скорость
       :if ($wan1qos > 5000 && $wan1qos != $spdmax && switch) do= { :set wan1qos $spdmax; set $switch false }
       :if ($wan1qos > 4000 && switch) do= { :set adjamt 512; :set $switch false }
       :if ($wan1qos > 3000 && switch) do= { :set adjamt 128; :set $switch false }
       :if ($wan1qos > 0 && switch) do= { :set adjamt 64; :set $switch false }
       :set spdadj (1 * $adjamt)
     }
     :set wan1qos ($wan1qos + $spdadj)
     :if ($wan1qos < $spdmin) do={ :set wan1qos $spdmin }
     :if ($wan1qos > $spdmax) do={ :set wan1qos $spdmax }
     :if ($wan1qos != $lastqos) do= {
       /system/script/run qos-env
       :log info "QoS: $wan1qos (Коррекция: $spdadj)"
     }
    }

    /system/script/ name=qos-env
    :global wan1qos
    :local qosrate $wan1qos
    /queue/tree/set "WAN_COMBINED" max-limit=($qosrate . "k")
    /queue/tree/set "1. VOIP" max-limit=($qosrate . "k") limit-at=(((32 * $qosrate) / 1000) . "k")
    /queue/tree/set "2. DNS" max-limit=($qosrate . "k") limit-at=(((16 * $qosrate) / 1000) . "k")
    /queue/tree/set "3. ICMP" max-limit=($qosrate . "k") limit-at=(((16 * $qosrate) / 1000) . "k")
    /queue/tree/set "4. ACK" max-limit=($qosrate . "k") limit-at=(((256 * $qosrate) / 1000) . "k")
    /queue/tree/set "5. UDP" max-limit=($qosrate . "k") limit-at=(((256 * $qosrate) / 1000) . "k")
    /queue/tree/set "6. QUIC" max-limit=($qosrate . "k") limit-at=(((256 * $qosrate) / 1000) . "k")
    /queue/tree/set "7. HTTP" max-limit=($qosrate . "k") limit-at=(((512 * $qosrate) / 1000) . "k")
    /queue/tree/set "8. OTHER" max-limit=($qosrate . "k") limit-at=(((512 * $qosrate) / 1000) . "k")
    /queue/tree/set "9. HTTP_BIG" max-limit=($qosrate . "k") limit-at=(((128 * $qosrate) / 1000) . "k")
    /queue/tree/set "10. TORRENTS" max-limit=($qosrate . "k") limit-at=(((64 * $qosrate) / 1000) . "k")

    Этот связанный скрипт будет корректировать лимиты QoS в зависимости от текущих потерь пакетов. Если лимит уже низкий — корректировки будут мелкими, если скорость выше — корректировки более активные, разумеется. Кроме ясности по поводу «switch / $switch», любые улучшения скрипта в целом приветствуются.
     
     
     
    rextended
    Guest
    #10
    0
    26.02.2023 14:52:00
    Исправил скрипт: я добавил некоторые части, но не исправлял и не проверял синтаксические ошибки. Код изначально был только концепцией, но теперь это реально работающий код. Исправил все синтаксические ошибки и отформатировал, сравните изменения. Некоторые ошибки: “else {” неправильно, должно быть “else={”, “do= {” неправильно, должно быть “do={” и так далее. Логику не проверял и не смотрел, делает ли скрипт то, что нужно — проверял только ошибки, чтобы код работал.

    :local spdmin    512
    :local spdsafe  2500
    :local spdmax  51200
    :local iface     “ether1_wan”
    :local srcadd    192.168.8.100
    :local pingcount 3
    :local pingadd   8.8.4.4
    :global avgpacketloss
    :global wan1qos
    :local lastqos       $wan1qos
    :local movingaverage 2
    :local curpacketloss “”
    :local adjamt        0
    :local spdadj        “”

    :if ([/interface ethernet get $iface running]) do={
       :local count [/ping address=$pingadd interface=$iface src-address=$srcadd size=28 interval=1 count=$pingcount]
       :local count 3
       :set curpacketloss ((($pingcount - $count) * 100) / $pingcount)
       :log info “Процент потерянных пингов: $curpacketloss% (принято $count из $pingcount)”
       :set avgpacketloss ((($avgpacketloss * ($movingaverage - 1)) + $curpacketloss) / $movingaverage)
       :log info “Средняя потеря пакетов: $avgpacketloss”
       :local switch true
       :if (($avgpacketloss > 10) and ($curpacketloss > $avgpacketloss)) do={
           # Потеря пакетов — уменьшаем скорость
           :if (($wan1qos > 5000) and $switch) do={ :set wan1qos $spdsafe; :set switch false }
           :if (($wan1qos > 4000) and $switch) do={ :set adjamt 512; :set switch false }
           :if (($wan1qos > 3000) and $switch) do={ :set adjamt 128; :set switch false }
           :if (($wan1qos > 0) and $switch) do={ :set adjamt 64; :set switch false }
           :set spdadj ($adjamt * -1)
       } else={
           # Потеря пакетов отсутствует или уменьшается — увеличиваем скорость
           :if (($wan1qos > 5000) and $switch and ($wan1qos != $spdmax)) do={ :set wan1qos $spdmax; :set switch false }
           :if (($wan1qos > 4000) and $switch) do={ :set adjamt 512; :set switch false }
           :if (($wan1qos > 3000) and $switch) do={ :set adjamt 128; :set switch false }
           :if (($wan1qos > 0) and $switch) do={ :set adjamt 64; :set switch false }
           :set spdadj ($adjamt * 1)
       }
       :set wan1qos ($wan1qos + $spdadj)
       :if ($wan1qos < $spdmin) do={ :set wan1qos $spdmin }
       :if ($wan1qos > $spdmax) do={ :set wan1qos $spdmax }
       :if ($wan1qos != $lastqos) do={
           /system script run "qos-env"
           :log info "QoS: $wan1qos (Регулировка: $spdadj)"
       }
    }

    :global wan1qos
    :local qosrate $wan1qos
    :local qosratek ($qosrate * 1024)
    /queue tree set “WAN_COMBINED” max-limit=$qosratek
    set “1. VOIP”     max-limit=$qosratek limit-at=($qosrate * 32)
    set “2. DNS”      max-limit=$qosratek limit-at=($qosrate * 16)
    set “3. ICMP”     max-limit=$qosratek limit-at=($qosrate * 16)
    set “4. ACK”      max-limit=$qosratek limit-at=($qosrate * 256)
    set “5. UDP”      max-limit=$qosratek limit-at=($qosrate * 256)
    set “6. QUIC”     max-limit=$qosratek limit-at=($qosrate * 256)
    set “7. HTTP”     max-limit=$qosratek limit-at=($qosrate * 512)
    set “8. OTHER”    max-limit=$qosratek limit-at=($qosrate * 512)
    set “9. HTTP_BIG” max-limit=$qosratek limit-at=($qosrate * 128)
    set “10. TORRENTS” max-limit=$qosratek limit-at=($qosrate * 64)
     
     
     
    fragtion
    Guest
    #11
    0
    26.02.2023 16:50:00
    Ого, это выглядит просто потрясающе!! Просто невероятная работа, я попробую и дам обратную связь. СПАСИБО, что нашли время пройтись по этому скрипту и так его прокачать 👏🏽 Извиняюсь, что захватил эту тему скриптом (я просто пытался найти лучший способ сделать “elseif”), если надо — можем перенести всё в отдельную ветку. Оригинальный скрипт пока толком не тестировался, а я уже думаю над несколькими улучшениями. Например, если скорость ограничена, но нагрузка низкая (никто в этот момент не сидит в интернете), throttle может слишком быстро снимать ограничение с интервалом в 3 секунды, так что, возможно, лучше увеличить скользящее среднее по большему количеству значений. Но это можно рассмотреть как отправную точку и посмотреть, что сработает лучше. Кроме того, он сильно нагружает логи, когда меняются все очереди, и я переживаю, что все изменения конфигурации могут записываться в NAND каждые 3 секунды? XD Не уверен, правда ли это и стоит ли беспокоиться.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры