RouterOS bevat een krachtige scripttaal voor het automatiseren van onderhoudstaken. U maakt door de gebruiker gedefinieerde scripts en koppelt deze aan gebeurtenissen.
Je kunt scripts opslaan in de Script-repository of ze rechtstreeks in de CLI schrijven. Veelvoorkomende triggers zijn onder meer de System Scheduler, de Traffic Monitoring Tool en gebeurtenissen van de Netwatch Tool.
Als u al bekend bent met scripting in RouterOS, wilt u misschien onze Tips & Tricks bekijken.
Regelstructuur
Het RouterOS-script is opgedeeld in een aantal commandoregels. De commandoregels worden een voor een uitgevoerd tot het einde van het script of totdat er een runtime-fout optreedt.
Command-line
De RouterOS CLI gebruikt de volgende commandosyntaxis:
[prefix] [path] command [uparam] [param=[value]] .. [param=[value]]
- [prefix] - het teken
:of/geeft aan of het volgende word een global command of een pad is. Een prefix is niet vereist wanneer het wordt aangeroepen vanuit het rootmenu of vanuit het menu dat relatief is aan het aangeroepen pad/commando. - [path] - relatief pad naar het gewenste menuniveau. Het is mogelijk niet vereist.
- command - een van de commando's die beschikbaar zijn op het opgegeven menuniveau.
- [uparam] - naamloze parameter, moet worden opgegeven als het commando dit vereist.
- [params] - een reeks benoemde parameters gevolgd door waarden (als een parameter een waarde vereist).
Het einde van de commandoregel wordt weergegeven door het token ; of NEWLINE.
Een commando dat is omsloten door (), [] of {} vereist geen einde-van-commando teken. Het einde van het commando wordt bepaald door de inhoud van het gehele script
:if ( true ) do={ :put "lala" }
Elke commandoregel binnen een andere commandoregel begint en eindigt met vierkante haken [] (operator voor het samenvoegen van commando's).
:put [/ip route get [find gateway=1.1.1.1]];
Merk op dat de bovenstaande code drie commandoregels bevat:
:put/ip route getfind gateway=1.1.1.1
Merk op dat het menuspecifieke commando find geen volledig pad vereist, omdat het pad wordt afgeleid van het pad van het bovenliggende commando.
Een commandoregel kan uit meer dan één fysieke regel worden opgebouwd door de regels voor regelsamenvoeging te volgen.
Fysieke lijn
Een fysieke regel is een reeks tekens die wordt afgesloten door een end-of-line (EOL)-reeks. Elk van de standaard regelafsluitingsreeksen van het platform kan worden gebruikt:
- Unix - ASCII LF;
- Windows - ASCII CR LF;
- mac - ASCII CR;
De standaard C-conventies voor newline-tekens kunnen worden gebruikt ( \n, \r\n tekens).
Comments
De volgende regels gelden voor een commentaar:
- Een commentaar begint met een hekje
#en eindigt aan het einde van de fysieke regel. - RouterOS ondersteunt geen commentaar over meerdere regels.
- Als er een
#teken in de string voorkomt, wordt dit niet als commentaar beschouwd.
# this is a comment
# continued comment in the next line
:global a; # comment describing variable
:global myStr "part of the string # is not a comment"
Regels samenvoegen
Twee of meer fysieke regels kunnen tot logische regels worden samengevoegd met het backslash-teken (\).
De volgende regels gelden voor het gebruik van de backslash als hulpmiddel om regels samen te voegen:
- Een regel die eindigt op een backslash kan geen commentaar bevatten.
- Een backslash zet een commentaar niet voort.
- Een backslash zet een token niet voort, behalve bij stringliteralen.
- Een backslash is elders op een regel buiten een stringliteraal niet toegestaan.
:if ($a = true \
and $b=false) do={ :put "$a $b"; }
:if ($a = true \ # bad comment (syntax error)
and $b=false) do={ :put "$a $b"; }
# comment \
continued is invalid (syntax error)
Witruimte tussen tokens
Witruimte kan gebruikt worden om tokens te scheiden. Witruimte tussen twee tokens is alleen nodig als hun samenvoeging als een ander token geïnterpreteerd zou kunnen worden. Voorbeeld:
{
:local a true; :local b false;
# whitespace is not required
:put (a&&b);
# whitespace is required
:put (a and b);
}
Witruimtetekens zijn niet toegestaan:
- tussen
<parameter>=. - tussen
from=,to=,step=,in=,do=,else=.
Voorbeeld:
#incorrect:
:for i from = 1 to = 2 do = { :put $i }
#correct syntax:
:for i from=1 to=2 do={ :put $i }
:for i from= 1 to= 2 do={ :put $i }
#incorrect
/ip route add gateway = 3.3.3.3
#correct
/ip route add gateway=3.3.3.3
Scopes
Variabelen kunnen alleen worden gebruikt in bepaalde delen van het script, scopes genoemd. Deze delen bepalen de zichtbaarheid van de variabele. Een variabele die binnen een blok wordt gedeclareerd, is alleen toegankelijk binnen dat blok en de geneste blokken daarvan, en alleen na het punt van declaratie.
Er zijn twee typen scopes: global en local.
Globale scope
De globale scope of root-scope is de standaardscope van het script. Deze wordt automatisch aangemaakt en kan niet worden uitgeschakeld.
Een globale variabele die door een ander script is ingesteld, kan worden benaderd door deze te declareren zonder er een waarde aan toe te kennen.
Het eerste script stelt bijvoorbeeld de waarde van myVar in op 3:
:global myVar 3
Om deze variabele vanuit een ander script te benaderen:
:global myVar
:put "myVar=$myVar"
Uitvoer:
myVar=3
Lokale scope
Je kunt groepen definiëren om de toegang tot variabelen te beperken; deze worden lokale scopes genoemd. Elke lokale scope wordt omsloten door accolades ({}).
{
:local a 3;
{
:local b 4;
:put ($a+$b);
} #line below will show variable b in light red color since it is not defined in this scope
:put ($a+$b);
}
Variabele b is in een lokale scope gedeclareerd en is niet toegankelijk na de sluitende accolade.
Elke regel die in de CLI wordt geschreven, wordt behandeld als een lokale scope. Zo is een gedefinieerde lokale variabele niet zichtbaar in de volgende commandoregel en genereert deze een syntaxisfout
[admin@MikroTik] > :local myVar a;
[admin@MikroTik] > :put $myVar
syntax error (line 1 column 7)
Gevaar Definieer geen global-variabele binnen een local-scope.
Ook als een variabele als global gedefinieerd kan worden, is deze alleen vanuit zijn eigen scope beschikbaar, tenzij ernaar wordt verwezen om buiten de scope zichtbaar te zijn.
{
:local a 3;
{
:global b 4;
}
:put ($a+$b);
}
De code geeft 3 als uitvoer omdat b buiten de scope niet zichtbaar is.
De volgende code lost het probleem op en geeft zoals bedoeld 7 als uitvoer:
{
:local a 3;
{
:global b 4;
}
:global b;
:put ($a+$b);
}
Keywords
De volgende woorden zijn sleutelwoorden en kunnen niet gebruikt worden als namen voor variabelen en functies:
and or in
Delimiters
De volgende tokens dienen als scheidingstekens in de grammatica:
() [] {} : ; $ /
Datatypen
De RouterOS-scripttaal heeft de volgende datatypen:
| Type | Description |
|---|---|
| num (number) | 64-bits signed integer, hexadecimale invoer mogelijk; |
| bool (boolean) | waarden kunnen true of false zijn. |
| str (string) | tekenreeks. |
| ip | IP-adres. |
| ip-prefix | IP-prefix. |
| ip6 | IPv6-adres. |
| ip6-prefix | IPv6-prefix. |
| id (interne ID) | Hexadecimale waarde voorafgegaan door het teken *. Elk menu-item heeft een toegewezen uniek nummer - het interne ID. |
| time | Datum- en tijdwaarde. |
| array | Reeks waarden georganiseerd in een array. |
| nil | Standaard variabeletype als er geen waarde is toegekend. |
Constante escape-reeksen
De volgende escapesequenties kunnen worden gebruikt om bepaalde speciale tekens binnen een string te definiëren:
| " | Voeg een dubbel aanhalingsteken in. |
| \ | Voeg een backslash in. |
| \n | Voeg een nieuwe regel in. |
| \r | Voeg een carriage return in. |
| \t | Voeg een horizontale tab in. |
| $ | Geeft het teken $ weer. Anders wordt $ gebruikt om naar de variabele te verwijzen. |
| \_ | Space. |
| \a | BEL (0x07). |
| \b | Backspace (0x08). |
| \f | Form feed (0x0C). |
| \v | Voeg een verticale tab in. |
| \xx | Een printbaar teken uit een hexwaarde. Hexgetallen moeten hoofdletters gebruiken. |
Bijvoorbeeld:
:put "\48\45\4C\4C\4F\r\nThis\r\nis\r\na\r\ntest";
geeft als uitvoer:
HELLO
This
is
a
test
Operators
Rekenkundige operatoren
In de RouterOS-scripttaal worden de gebruikelijke rekenkundige operatoren ondersteund:
| Operator | Description | Example |
|---|---|---|
+ |
binaire optelling | :put (3+4); |
- |
binaire aftrekking | :put (1-6); |
* |
binaire vermenigvuldiging | :put (4*5); |
/ |
binaire deling | :put (10 / 2); :put ((10)/2) |
% |
modulo-bewerking | :put (5 % 3); |
- |
unaire negatie | { :local a 1; :put (-a); } |
Merk op dat u voor de deling haakjes of spaties rond het deeltal moet gebruiken, zodat het niet ten onrechte als een IP-adres wordt gezien.
Relationele operatoren
| Operator | Description | Example |
|---|---|---|
< |
less | :put (3<4); |
> |
greater | :put (3>4); |
= |
equal | :put (2=2); |
<= |
kleiner dan of gelijk aan | |
>= |
groter dan of gelijk aan | |
!= |
niet gelijk aan |
Om een expressie te ontkennen, kunt u <expression>=false gebruiken. Om bijvoorbeeld alle interfaces af te drukken die geen "ethernet" zijn, kunt u expressie-negatie zo gebruiken:
/interface/print where (name~"ether")=false
Of om het tegenovergestelde te doen, kunt u <expression>=true gebruiken:
/interface/print where (name~"ether")=true
Logische operatoren
| Operator | Description | Example |
|---|---|---|
! |
logische NOT | :put (!true); |
&&, and |
logische AND | :put (true&&true) |
||, or |
logische OR | :put (true||false); |
in |
:put (1.1.1.1/32 in 1.0.0.0/8); |
Bitwise Operators
Bitwise operators werken alleen op de datatypes IP en IPv6-adres.
| Operator | Description | Example |
|---|---|---|
~ |
Bitinversie. | :put (~0.0.0.0) :put (~::ffff) |
| |
Bitwise OR voert een logische OR-bewerking uit op elk paar corresponderende bits. In elk paar is het resultaat “1” als een van de bits of beide bits “1” zijn, anders is het resultaat “0”. | :put (192.168.88.0|0.0.0.255) :put (2001::1|::ffff) |
^ |
Bitwise XOR is hetzelfde als OR, maar het resultaat op elke positie is “1” als twee bits niet gelijk zijn, en “0” als de bits gelijk zijn. | :put (1.1.1.1^255.255.0.0) :put (2001::ffff:1^::ffff:0) |
& |
Bitwise AND geeft als resultaat “1” als het eerste en het tweede bit “1” zijn. Anders is het resultaat “0”. | :put (192.168.88.77&255.255.255.0) :put (2001::1111&ffff::) |
<< |
Links verschuiven met een opgegeven aantal bits, niet ondersteund voor het IPv6-adres datatype. | :put (192.168.88.77<<8) |
>> |
Schuif naar rechts met een gegeven aantal bits; niet ondersteund voor het IPv6-adres datatype. | :put (192.168.88.77>>24) |
Bereken bijvoorbeeld een subnetadres uit een gegeven IP en CIDR-netmask met de operator &:
{
:local IP 192.168.88.77;
:local CIDRnetmask 255.255.255.0;
:put ($IP&$CIDRnetmask);
}
Haal de laatste 8 bits op uit de opgegeven IP-adressen:
:put (192.168.88.77&0.0.0.255);
Gebruik de operator | en een omgekeerd CIDR-masker om het broadcastadres te berekenen:
{
:local IP 192.168.88.77;
:local Network 192.168.88.0;
:local CIDRnetmask 255.255.255.0;
:local InvertedCIDR (~$CIDRnetmask);
:put ($Network|$InvertedCIDR)
}
Concatenatie-operatoren
| Operator | Description | Example |
|---|---|---|
. |
Voegt twee strings samen. | :put ("concatenate" . " " . "string"); |
, |
Voegt twee arrays samen of voegt een element toe aan de array. | :put ({1;2;3} , 5 ); |
Het is mogelijk om variabelewaarden rechtstreeks aan strings toe te voegen zonder een concatenatie-operator:
:global myVar "world";
# value can be added with concatenation operator
:put ("Hello " . $myVar);
# or without operator
:put "Hello $myVar";
Met $[] en $() kunt u expressies uitvoeren en de resulterende waarde in strings invoegen:
:local a 5;
:local b 6;
:put " 5x6 = $($a * $b)";
:put " We have $[ :len [/ip route find] ] routes";
Andere operatoren
| Operator | Description | Example |
|---|---|---|
[] |
Commandosubstitutie kan slechts één commandoregel bevatten` | :put [ :len "my test string"; ]; |
() |
Subexpressie- of groeperingsoperator. | :put ( "value is " . (4+5)); |
$ |
Substitutieoperator. | :global a 5; :put $a; |
~ |
De binaire operator die een waarde vergelijkt met een POSIX extended reguliere expressie. | Toon alle routes waarvan de gateway eindigt op 202: /ip/route/print where gateway~"^[0-9 \\.]*202\$" |
-> |
Haal een array-element op via de sleutel. | [admin@x86] >:global aaa {a=1;b=2}``[admin@x86] > :put ($aaa->"a")``1``[admin@x86] > :put ($aaa->"b")``2 |
Variables
De scripttaal kent twee soorten variabelen:
- global - Toegankelijk vanuit alle scripts die door de huidige gebruiker zijn gemaakt, gedefinieerd met het sleutelwoord
global. - local - Alleen toegankelijk binnen de huidige scope, gedefinieerd met het sleutelwoord
local.
Variabelen kunnen ongedefinieerd zijn. Wanneer dat gebeurt, zoekt de parser naar ingebouwde variabelen die door de applicatie worden aangeleverd. Zo levert het DHCP lease-script bijvoorbeeld verschillende ingebouwde variabelen:
/system script
add name=myLeaseScript policy=\
ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api \
source=":log info \$leaseActIP\r\
\n:log info \$leaseActMAC\r\
\n:log info \$leaseServerName\r\
\n:log info \$leaseBound"
/ip dhcp-server set myServer lease-script=myLeaseScript
Behalve de ingebouwde RouterOS-variabelen moet elke variabele vóór gebruik worden gedeclareerd met het sleutelwoord local of global. Het gebruik van een niet-gedeclareerde variabele resulteert in een compilatiefout. Bijvoorbeeld:
# following code will result in compilation error, because myVar is used without declaration
:set myVar "my value";
:put $myVar
Correcte code:
:local myVar;
:set myVar "my value";
:put $myVar;
Geldige tekens in variabelenamen zijn letters en cijfers. Als een variabelenaam een ander teken dan letters of cijfers bevat (inclusief operatoren), plaats deze dan tussen dubbele aanhalingstekens (""). Voorbeeld:
#valid variable name
:local myVar;
#invalid variable name
:local my-var;
#valid because double quoted
:global "my-var";
Als een variabele eerst zonder waarde wordt gedefinieerd, wordt het datatype van de variabele ingesteld op nil; anders bepaalt de scripting-engine het datatype automatisch. Soms is conversie van het ene datatype naar het andere nodig. Dit kan worden bereikt met dataconversiecommando's. Voorbeeld:
#convert string to array
:local myStr "1,2,3,4,5";
:put [:typeof $myStr];
:local myArr [:toarray $myStr];
:put [:typeof $myArr]
Variabelenamen zijn hoofdlettergevoelig.
:local myVar "hello"
# following line will generate error, because variable myVAr is not defined
:put $myVAr
# correct code
:put $myVar
Het commando set zonder waarde maakt een variabele ongedefinieerd:
#remove variable from environment
:global myVar "myValue"
:set myVar;
Gereserveerde variabelenamen
Alle ingebouwde RouterOS-eigenschappen zijn gereserveerde variabelen. Variabelen die met dezelfde namen als ingebouwde RouterOS-eigenschappen zijn gedefinieerd, kunnen fouten veroorzaken. Kies andere namen om dit te voorkomen.
Het volgende script werkt bijvoorbeeld niet:
{
:local type "ether1";
/interface print where name=$type;
}
Maar het werkt wel met andere gedefinieerde variabelen:
{
:local customname "ether1";
/interface print where name=$customname;
}
Commands
Globale commando's
Elk globaal commando moet beginnen met het token :; anders wordt het als een variabele behandeld.
| Command | Syntax | Description | Example |
|---|---|---|---|
| / | Ga naar het hoofdmenu. | ||
| .. | Ga één menuniveau terug. | ||
| ? | Toon alle beschikbare menucommando's en korte beschrijvingen. | ||
| global | :global <var> [<value>] |
Definieer een globale variabele. | :global myVar "something"; :put $myVar; |
| local | :local <var> [<value>] |
Definieer de lokale variabele. | { :local myLocalVar "I am local"; :put $myLocalVar; } |
| beep | :beep frequency=[num] length=[num] |
Laat de ingebouwde luidspreker piepen. | |
| convert | :convert from=[arg] to=[arg] transform=[arg] |
Converteert de opgegeven waarde van het ene formaat naar het andere. Standaard wordt een automatisch geparseerde waarde gebruikt als het formaat from niet is opgegeven (zo wordt "001" bijvoorbeeld "1", en "10.1" wordt "10.0.0.1", enzovoort). from - Geeft het formaat van de waarde aan: base32, base64, bit-array-lsb, bit-array-msb, byte-array, hex, num, raw, url. to - Geeft het formaat van de uitvoerwaarde aan: base32, base64, bit-array-lsb, bit-array-msb, byte-array, hex, num, raw, url. transform - Geeft aan hoe waarden getransformeerd moeten worden: lc (zet de waarde om naar kleine letters), uc (hoofdletters), lcfirst (eerste waarde naar kleine letters), ucfirst (eerste waarde naar hoofdletters), crlf, ed25519-private-to-x25519-private, none, rot 13, x25519-private-to-x25519-public, ed25519-private-to-ed25519-public, ed25519-public-to-x25519-public, md5, reverse (keert tekst om), sha512. |
:put [:convert 001 to=hex ] 31 :put [:convert [/ip dhcp-client/option/get hostname raw-value] from=hex to=raw ] MikroTik :put [:convert transform=lc "AAA"] aaa |
| delay | :delay <time> |
Doe gedurende een bepaalde periode niets. | |
| environment | :environment print <start> |
Toont informatie over geïnitialiseerde variabelen. | :global myVar true; :environment print; |
| error | :error <output> |
Genereer een consolefout en stop de uitvoering van het script. | |
| execute | :execute <expression> |
Voer het script uit op de achtergrond. Het resultaat kan naar een bestand worden geschreven door een file parameter in te stellen of naar de CLI worden geprint door as-string in te stellen. Bij gebruik van de parameter as-string wordt het uitgevoerde script geblokkeerd (niet op de achtergrond uitgevoerd). Uitgevoerde scripts kunnen niet groter zijn dan 64 kB. |
{ :local j [:execute {/interface print follow where [:log info ~Sname~]}]; :delay 10s; :onerror e {/system script job remove $j}} |
| find | :find <arg> <arg> <start> |
Geeft de positie van een substring of een array-element terug. | :put [:find "abc" "a" -1]; |
| grep | :grep script=[str] pattern=[expression] after=[num] before=[num] filename=[str] |
Voer het opgegeven script uit in de terminal en print de regels die overeenkomen met een gegeven pattern. De parameters after en before bepalen hoeveel regels er aanvullend vóór en na de overeenkomende regel worden geprint. Resultaten kunnen direct in een bestand worden opgeslagen met de parameter filename. |
:grep script="/interface print" pattern="ether" after=1 before=1 filename=results.txt |
| jobname | :jobname | Geeft de huidige scriptnaam terug. | Beperk scriptuitvoering tot één instantie :if ([/system script job print count-only as-value where script=[:jobname] ] > 1) do={ :error "script instance already running" } |
| len | :len <expression> |
Geeft de lengte van de string of het aantal array-elementen terug. | :put [:len "length=8"]; |
| log | :log <topic> <message> |
Schrijf een bericht naar het systeemlog. De beschikbare topics zijn debug, error, info en warning. |
:log info "Hello from script"; |
| onerror | :onerror <var_name> in={<command>} do={<expression>} |
Vang fouten op en verkrijg foutdetails. Het blok do={...} wordt uitgevoerd wanneer het blok in={...} een fout bevat, en de foutdetails worden weggeschreven in de variabele <var_name>. De volgorde van de parameters is belangrijk. De parameter error moet vóór het blok do worden ingesteld, anders ziet het blok do de lokale variabele niet. :onerror geeft false terug (als er geen fout is) en true (als er een fout is), tenzij anders opgegeven (met commando's zoals :return of :error), zodat het gebruikt kan worden in scripts met een :if conditie. |
:onerror errorName in={ :error "failure" } do={ :put "Critical $errorName" } |
| parse | :parse <expression> |
Parseert de string en geeft de geparseerde consolecommando's terug. Kan als functie worden gebruikt. | :global myFunc [:parse ":put hello!"]; $myFunc; |
| pick | :pick <var> <start> [<end>] |
Geeft een reeks elementen of een substring terug. Als de count niet is opgegeven, wordt er slechts één element uit een array teruggegeven. var - waarde waaruit elementen gekozen worden.start - element waar het kiezen begint (de index van het eerste element is 0).end - eindindex (het element op deze index wordt niet meegenomen). |
[admin@MikroTik] > :put [:pick "abcde" 1 3]``bc |
| put | :put <expression> |
Toont het meegegeven argument in de terminal. | :put "Hello world" |
| range | :range <var> <var> |
Maakt een array aan op basis van het opgegeven bereik. | :put [:range 2 8] 2;3;4;5;6;7;8 |
| resolve | :resolve <arg> [<domain-name>][<server>][<server-port>][<type>] |
Geeft het IP-adres terug van de opgegeven DNS-naam domain-name - DNS-naam die omgezet moet worden.server - Specifieke server die gebruikt wordt om de DNS-naam om te zetten (de teruggegeven resultaten worden niet gecachet).server-port - Serverpoort waarmee verbonden wordt.type - any/any6/ipv4/ipv6:any - Probeer ipv4 om te zetten, bij mislukking probeer ipv6.any6 - Probeer ipv6 om te zetten, bij mislukking probeer ipv4.ipv4 - Probeer alleen ipv4 om te zetten.ipv6 - Probeer alleen ipv6 om te zetten. |
:put [:resolve "www.mikrotik.com"]; :put [:resolve domain-name="www.mikrotik.com"]; :put [:resolve domain-name="www.mikrotik.com" server=192.168.88.1 server-port=53]; :put [:resolve domain-name="www.mikrotik.com" type=ipv6]; |
| retry | :onerror e {:retry command=<expr> delay=[num] max=[num]} do={<expr>} |
Probeer het opgegeven commando max keer uit te voeren met een opgegeven delay in seconden tussen de pogingen. Bij mislukking wordt het commando in het do={}-blok uitgevoerd. |
:onerror e {:retry command={abc} delay=1 max=2} do={:put "got error"} |
| typeof | :typeof <var> |
Geeft het datatype van de opgegeven variabele terug. | :put [:typeof 4]; |
| rndnum | :rndnum from=[num] to=[num] |
Generator van willekeurige getallen. | :put [:rndnum from=1 to=99]; |
| rndstr | :rndstr from=[str] length=[num] |
Generator van willekeurige strings. from geeft de tekens op waaruit de string wordt opgebouwd en staat standaard op alle ASCII-letters en cijfers. length geeft de lengte op van de aan te maken string en staat standaard op 16. |
:put [:rndstr from="abcdef%^&``" length=33]; |
| set | :set <var> [<value>] |
Ken een waarde toe aan een gedeclareerde variabele. | :global a; :set a true; |
| serialize | :serialize [<value>] to=[arg] |
Serialiseer de opgegeven waarde/array naar JSON- of dsv-formaat (delimiter separated values). value geeft aan welke waarden verwerkt moeten worden. to geeft het formaat aan - json, dsv delimiter stelt de "separator" in. order geeft de volgorde voor variabelen aan. options geeft aanvullende opties aan*:* json.pretty - maakt de JSON-uitvoer visueel aantrekkelijker;json.no-string-conversion - voorkomt impliciete conversies van het console string type naar het json number type;dsv.wrap-strings - plaatst stringwaarden tussen aanhalingstekens;dsv.ignore-size - als arraywaarden verschillende groottes hebben, bijvoorbeeld <code>a=(1,2);b=(3,4);c=(5,6,7)</code>, omzeilt deze optie de fout <code>array size mismatch</code> en zet "lege" waarden in die posities.dsv.remap - voegt een array van dictionaries samen tot een enkele dictionary (nuttig bij het werken met "<code>print as-value</code>") file-name maakt het mogelijk om de uitvoer van het commando naar een bestand te genereren (beschikbaar voor download in de sectie "/files"). |
:put [:serialize value=a,b,c to=json]``["a","b","c"]``:local test {a=(1,2,3);b=(4,5,6);c=(7,"text",9)}; :put [ :serialize to=dsv delimiter=";" value=$test order=("c","a","b") ]``c;a;b``7;1;4``text;2;5``9;3;6``:global var ({ "string"="1234"; "number"=1234 });:put [ :serialize to=json value=$var ]``{"number":1234,"string":1234.000000}``:put [ :serialize to=json value=$var options=json.no-string-conversion ]``{"number":1234,"string":"1234"}``:put [:serialize to=dsv options=dsv.remap delimiter="#" [/ip/address/print as-value]]``.id#address#comment#interface#network``*1#192.168.88.1/24#defconf#bridge#192.168.88.0``*2#192.168.69.190/24##ether1#192.168.69.0 |
| deserialize | :deserialize [<value>] from=[arg] |
Deserialiseert de opgegeven waarde/array vanuit JSON- of dsv-formaat (delimiter separated values). from geeft het formaat aan - json, dsv delimiter stelt het "scheidingsteken" in. options geeft aanvullende opties aan*:* dsv.plain - deserialiseert elke regel als een array (de invoer heeft geen header of kolomnamen);dsv.array - verwacht een header (kolomnamen) en geeft een array van dictionaries terug, waarbij waarden worden gekoppeld aan de kolomnamen uit de header.json.no-string-conversion - voorkomt impliciete conversies van het json string-type naar consolewaarden (number, ip, enzovoort). |
:put [:deserialize from=json value="[\"a\",\"b\",\"c\"]"]``a;b;c``:put ([ :deserialize from=dsv delimiter=";" value="a;b;c\n1;findme;3" options=dsv.plain ]->1->1) findme``:put ([ :deserialize from=dsv delimiter=";" value="a;b;c\n1;findme;3" options=dsv.plain ]->0->1) ``b``:put ([:deserialize from=dsv "a;b;c\n1;2;3\n4;5;6" delimiter=";" options=dsv.array]->1->"b") ``5``:put ([:deserialize from=dsv "a;b;c\n1;2;3\n4;5;6" delimiter=";" options=dsv.array]->0->"c") ``3``:put [typeof ([:deserialize "{ \"str\": \"123\" }" from=json options=json.no-string-conversion]->"str")]``str``:deserialize [/file/get file.json contents] from=json |
| time | :time <expression> |
Geeft het tijdsinterval terug dat nodig is om de opgegeven expressie uit te voeren. | :put [:time {:for i from=1 to=10 do={ :delay 100ms }}]; |
| timestamp | :timestamp [use-tz] |
Geeft de tijd terug sinds epoch, waarbij epoch 1 januari 1970 (donderdag) is, schrikkelseconden niet meegerekend. De tijd wordt standaard in UTC teruggegeven. Gebruik de parameter use-tz om de tijdstempel terug te geven aangepast aan de op de router geconfigureerde tijdzone. |
[admin@MikroTik] > :put [:timestamp]``2735w21:41:43.481891543of[admin@MikroTik] > :put [:timestamp]``2735w1d21:41:43.481891543met de dagoffset. |
| toarray | :toarray <var> |
Zet een variabele om naar een array. | |
| tobool | :tobool <var> |
Zet een variabele om naar een boolean. | |
| toid | :toid <var> |
Zet een variabele om naar een intern ID. | |
| toip | :toip <var> |
Zet een variabele om naar een IP-adres. | |
| toip6 | :toip6 <var> |
Zet een variabele om naar een IPv6-adres. | |
| tonum | :tonum <var> |
Zet een variabele om naar een integer. | |
| tostr | :tostr <var> |
Zet een variabele om naar een string. | |
| totime | :totime <var> |
Zet een variabele om naar tijd. | |
| tonsec | :tonsec <var> |
Zet een tijd om naar nanoseconden. | :put [:tonsec value=10:00] 36000000000000 |
| tocrlf | :tocrlf <var> |
Zet regeleindes om naar CRLF's. | :put [:tocrlf "AAA\r\nBBB\r\nCCC" ]``AAA``BBB``CCC |
| tolf | :tolf <var> |
Zet regeleindes om naar LF's. | :put [:tolf "AAA\nBBB\nCCC" ]``AAA`` BBB`` CCC |
| nothing | :nothing |
Geeft een waarde van niets terug. | :if ([:nothing] = 0) do={:put true} else={:put false} false :if ([:nothing] > 0) do={:put true} else={:put false} false :if ([:nothing] < 0) do={:put true} else={:put false} |
Als een functie voor het converteren van een variabeletype het nieuwe formaat niet op de aangeleverde data kan toepassen, is de uitvoer leeg.
Als u bijvoorbeeld het commando :tonum <var> uitvoert op een variabele met een niet-gehele waarde zoals "23.8" of "cow&chicken", is het resultaat leeg en wordt het datatype getoond als nil.
Veelgebruikte commando's
De volgende commando's zijn beschikbaar vanuit de meeste submenu's:
| Command | Syntax | Description |
|---|---|---|
| add | add <param>=<value>..<param>=<value> |
Nieuw item toevoegen. Dit commando heeft meestal dezelfde argumenten als set, behalve het itemnummer-argument. Het voegt een nieuw item toe met de waarden die u hebt opgegeven, meestal aan het einde van de itemlijst, op plaatsen waar de volgorde van items relevant is. Er zijn enkele verplichte eigenschappen die u moet opgeven, zoals de interface voor een nieuw adres, terwijl andere eigenschappen op standaardwaarden worden gezet tenzij u ze expliciet opgeeft. Geeft het interne nummer terug van het item dat is toegevoegd.Veelgebruikte parameters:copy-from - Kopieert een bestaand item. Het neemt de standaardwaarden van de eigenschappen van een nieuw item over van een ander item. Als u geen exacte kopie wilt maken, kunt u voor sommige eigenschappen nieuwe waarden opgeven. Bij het kopiëren van items die een naam hebben, zult u de kopie meestal een nieuwe naam moeten geven.place-before - Plaatst een nieuw item vóór een bestaand item op een opgegeven positie. Zo hoeft u het move-commando niet te gebruiken nadat u een item aan de lijst hebt toegevoegd.disabled - Bepaalt de uitgeschakelde/ingeschakelde status van het nieuw toegevoegde item (of de items).comment - Bevat de beschrijving van een nieuw aangemaakt item. |
| remove | remove <id> |
Verwijder het geselecteerde item. |
| enable | enable <id> |
Schakel het geselecteerde item in. |
| disable | disable <id> |
Schakel het geselecteerde item uit. |
| set | set <id> <param>=<value>..<param>=<value> |
Wijzig de parameter van de geselecteerde items, er kunnen meerdere parameters tegelijk worden opgegeven. De parameter kan ongedaan worden gemaakt door '!' vóór de parameter te plaatsen. Voorbeeld: /ip firewall filter add chain=blah action=accept protocol=tcp port=123 nth=4,2 print set 0 !port chain=blah2 !nth protocol=udp |
| get | get <id> <param>=<value> |
Haal de parameterwaarde van het geselecteerde item op. Wordt standaard niet in de terminal weergegeven. Bij gebruik in combinatie met het :put commando wordt de opgehaalde waarde in de terminal getoond, bijvoorbeeld: :put [/system/resource/get version] toont de versie van RouterOS die op het apparaat is geïnstalleerd. |
print <param><param>=[<value>] |
Toont menu-items. De uitvoer hangt af van de opgegeven print parameters. Toont alle informatie die vanaf een bepaald commandoniveau toegankelijk is. Zo toont /system/clock/print de systeemdatum en -tijd, toont /ip/route/print alle routes, enzovoort. Als er op het huidige niveau een lijst met items is en deze zijn niet alleen-lezen, kent het print-commando ook nummers toe die door alle commando's worden gebruikt die met items in deze lijst werken. |
|
| export | export [file=<value>] |
Exporteer de configuratie van het huidige menu en de bijbehorende submenu's (indien aanwezig). Als de parameter file is opgegeven, wordt de uitvoer naar het bestand met de extensie '.rsc' geschreven, anders wordt de uitvoer naar de terminal geprint. Geëxporteerde commando's kunnen worden geïmporteerd met het import-commando. |
| edit | edit <id> <param> |
Bewerk de eigenschap van geselecteerde items in de ingebouwde teksteditor. Kan worden gebruikt om waarden te bewerken van eigenschappen die veel tekst bevatten, zoals scripts, maar het werkt met alle bewerkbare eigenschappen. Afhankelijk van de mogelijkheden van de terminal wordt er een schermvullende editor of een editor met één regel gestart. Het bewerkingsveld voor consolescripts is beperkt tot 30 duizend tekens. |
| find | find <expression> |
Geeft een lijst met interne nummers terug van items die door een gegeven expressie worden gematcht. Heeft dezelfde argumenten als set, plus de vlagargumenten zoals disabled of active die de waarden yes of no aannemen afhankelijk van de waarde van de betreffende vlag. Om alle vlaggen en hun namen te zien, kijkt u bovenaan de uitvoer van het commando print. |
| move | move <id> [<id>] |
Wijzigt de volgorde van items in de lijst. Het eerste argument geeft aan welk(e) item(s) worden verplaatst. Het tweede argument geeft het item aan waarvóór alle te verplaatsen items moeten worden geplaatst (ze worden aan het einde van de lijst geplaatst als het tweede argument wordt weggelaten). |
| reset | reset <id> [<param>=<value>] |
Zet parameters terug naar de standaardwaarden. U kunt in hetzelfde commando ook parameters met argumenten opnemen, zodat u instellingen tegelijkertijd kunt resetten en configureren. |
| comment | comment <id> <value> |
Maakt het mogelijk het geselecteerde item van commentaar te voorzien. |
import
Het import-commando is beschikbaar vanuit het hoofdmenu en wordt gebruikt om configuratie te importeren uit bestanden die zijn aangemaakt met een export commando of handmatig zijn geschreven.
[admin@admin] > do { import test.rsc } on-error={ :put "Failure" }
Failure
De parameter onerror kan worden gebruikt om de fouten op te vangen:
[admin@admin] > onerror e in={ import test.rsc } do={ :put "Failure - $e" }
Failure - Script Error: bad command name this (line 1 column 1)
Daarnaast heeft het commando import nieuwe opties in de verbose-modus: de parameter dry-run is bedoeld voor debuggen en kan worden gebruikt om fouten te vinden zonder de configuratie te wijzigen.
[admin@admin] > import test.rsc verbose=yes dry-run
#line 1
this
bad command name this (line 1 column 1)
...
Script Error: found 5 error(s) in import file
print-parameters
Er zijn verschillende algemene parameters beschikbaar voor het print commando:
| Parameter | Description | Example |
|---|---|---|
| append | ||
| as-value | Toont de uitvoer als een array van parameters en hun waarden. | :put [/ip address print as-value] |
| brief | Beknopte uitvoer is doorgaans minimalistisch en wordt weergegeven als een tabel met items met de meest gebruikte parameters. | |
| detail | Toont een gedetailleerde beschrijving; de uitvoer is minder goed leesbaar dan de beknopte uitvoer, maar kan nuttig zijn om alle parameters te bekijken. | |
| count-only | Toont alleen het aantal items in het huidige menu. | |
| file | Schrijf de uitvoer naar een bestand. | |
| follow | Toont alle huidige entries en volgt nieuwe entries totdat op <kbd>ctrl</kbd>-<kbd>c</kbd> wordt gedrukt. Kan bijvoorbeeld worden gebruikt bij het bekijken van logregels. | /log print follow |
| follow-only | Toont en volgt alleen nieuwe entries totdat op <kbd>ctrl</kbd>-<kbd>c</kbd> wordt gedrukt. Kan bijvoorbeeld worden gebruikt wanneer u nieuwe logregels wilt zien. | /log print follow-only |
| from | Toont alleen parameters van een opgegeven item. | /user print from=admin |
| interval | Print de uitvoer doorlopend met een gekozen tijdsinterval, handig om wijzigingen te volgen wanneer follow geen optie is |
/interface print interval=2 |
| terse | Toon details in een compact en machinevriendelijk formaat. | |
| value-list | De gegevens worden weergegeven in een tabel, waarbij parameters per regel en beschikbare items per kolom gescheiden zijn (kan gebruikt worden voor parsingdoeleinden). | |
| order-by | Sorteer de uitvoer op een of meer eigenschappen. Zet - vóór de naam van de eigenschap voor aflopende volgorde. Er kunnen maximaal drie sorteervelden worden opgegeven. |
/ip/arp/print order-by=address``/interface/print order-by=-link-downs proplist=name,link-downs``/interface/ethernet/print stats order-by=-driver-rx-packet where running |
| without-paging | Als de uitvoer niet op het consolescherm past, druk dan alle informatie in één geheel af zonder onderbrekingen. | |
| where | Expressies gevolgd door where parameters kunnen worden gebruikt om overeenkomende entries eruit te filteren. |
/ip route print where interface="ether1" |
| about | Geeft items terug die de parameter about hebben, zoals informatie of waarschuwingen van het type "managed by CAPsMAN " |
/interface wifi print where about |
Er kan meer dan één parameter tegelijk worden opgegeven, bijvoorbeeld /ip route print count-only interval=1 where interface="ether1"
Lussen en voorwaardelijke statements
Loops
| Command | Syntax | Description |
|---|---|---|
do..while |
:do { <commands> } while=( <conditions> ); :while ( <conditions> ) do={ <commands> }; |
Voer commando's uit totdat aan een bepaalde voorwaarde is voldaan. |
for |
:for <var> from=<int> to=<int> step=<int> do={ <commands> } |
Voer commando's uit gedurende een bepaald aantal iteraties |
foreach |
:foreach <var> in=<array> do={ <commands> }; |
Voer commando's uit voor elk element in een lijst. |
Voorwaardelijke instructie
| Command | Syntax | Description |
|---|---|---|
if |
:if (<condition>) do={<commands>} else={<commands>} |
Als een gegeven voorwaarde true is, voer dan de commando's in het do blok uit, voer anders de commando's in het else blok uit (indien opgegeven). |
Voorbeeld:
{
:local myBool true;
:if ($myBool = false) do={ :put "value is false" } else={ :put "value is true" }
}
Functions
Functies worden op vergelijkbare wijze gedefinieerd als globale variabelen, met het sleutelwoord global gevolgd door de operator do=, waarna de body tussen accolades ({}) staat.
Er zijn twee manieren om argumenten door te geven:
- Geef arg met een specifieke naam door.
- Geef de waarde door zonder arg-naam; in dat geval wordt arg "1", "2" .. "n" gebruikt om naar de waarde te verwijzen.
#define function and run it
:global myFunc do={:put "hello from function"}
$myFunc
output:
hello from function
#pass arguments to the function
:global myFunc do={:put "arg a=$a"; :put "arg '1'=$1"}
$myFunc a="this is arg a value" "this is arg1 value"
output:
arg a=this is arg a value
arg '1'=this is arg1 value
Je kunt een functiewaarde teruggeven met het commando :return.
:global myFunc do={ :return ($a + $b)}
:put [$myFunc a=6 b=2]
output:
8
Je kunt zelfs een bestaand script uit de scriptomgeving klonen en het als functie gebruiken.
#add script
/system script add name=myScript source=":put \"Hello \$myVar !\""
:global myFunc [:parse [/system script get myScript source]]
$myFunc myVar=world
output:
Hello world !
De scripttaal maakt het ook mogelijk indirect functies te maken door middel van het commando :parse.
Als de functie een gedefinieerde globale variabele bevat waarvan de naam overeenkomt met de naam van de doorgegeven parameter, wordt de globaal gedefinieerde variabele genegeerd, voor compatibiliteit met scripts die voor oudere versies zijn geschreven. Vermijd het gebruik van parameters met dezelfde naam als globale variabelen.
Bijvoorbeeld:
:global my2 "123"
:global myFunc do={ :global my2; :put $my2; :set my2 "lala"; :put $my2 }
$myFunc my2=1234
:put "global value $my2"
De uitvoer zal zijn:
1234
lala
global value 123
Om een functie vanuit een andere functie aan te roepen (een geneste functie), declareert u de naam ervan zoals u dat bij een variabele zou doen:
:global funcA do={ :return 5 }
:global funcB do={
:global funcA;
:return ([$funcA] + 4)
}
:put [$funcB]
Output:
9
Runtime-fouten opvangen
RouterOS-scripting maakt het mogelijk runtime-fouten op te vangen die anders het script onverwacht zouden beëindigen. Het commando :resolve genereert bijvoorbeeld een fout en breekt het script af als het mislukt.
[admin@MikroTik] > { :put [:resolve www.example.com]; :put "lala";}
failure: dns name does not exist
Je kunt deze fout opvangen en verdergaan met het script:
:onerror e {:put [:resolve www.example.com]} do={:put "resolver failed"}
:put "print after failure"
output:
resolver failed
print after failure
Bewerkingen met arrays
Als een sleutelnaam in een array een ander teken dan een kleine letter bevat, moet deze tussen aanhalingstekens worden gezet. Bijvoorbeeld:
[admin@ce0] > {:local a { "aX"=1; ay=2 }; :put ($a->"aX")}
1
foreach commando kan worden gebruikt om door sleutels en elementen te lopen:
[admin@ce0] > :foreach k,v in={2; "aX"=1; y=2; 5} do={:put ("$k=$v")}
0=2
1=5
aX=1
y=2
Als het foreach commando met één argument wordt aangeroepen, geeft het de elementwaarde terug:
[admin@ce0] > :foreach v in={2; "aX"=1; y=2; 5} do={:put ("$v")}
2
5
1
2
Als een array-element een sleutel heeft, worden die elementen alfabetisch gesorteerd; elementen zonder sleutel worden vóór elementen met sleutel geplaatst en behouden hun volgorde (zoals geïllustreerd in het vorige voorbeeld).
Het is mogelijk om de waarde van een enkel element te wijzigen met behulp van de sleutelnaam:
[admin@MikroTik] > :global a {x=1; y=2}
[admin@MikroTik] > :set ($a->"x") 5
[admin@MikroTik] > :environment print
a={x=5; y=2}
Scriptrechten
Afhankelijk van hoe een script wordt aangeroepen, kan het:
- Gebruik zijn eigen rechten.
- Neem de rechten van de aanroeper over.
Denk bijvoorbeeld aan een gebruiker met volledige rechten en een script waarvoor geen rechten zijn ingesteld:
/user/print
Columns: NAME, GROUP, LAST-LOGGED-IN, INACTIVITY-POLICY
# NAME GROUP LAST-LOGGED-IN INACTIVITY-POLICY
;;; system default user
0 admin full 2025-07-22 17:09:59 none
/system script
add dont-require-permissions=no name=add-dhcp-no-perms owner=admin policy="" sour
ce="/ip dhcp-client add interface=ether2; put \"Added DHCP client on ether2!\""
Laten we kijken wat er gebeurt als we het script uitvoeren met en zonder de parameter use-script-permissions:
[admin@MikroTik] > system/script/run add-dhcp-no-perms use-script-permissions
not enough permissions (9)
[admin@MikroTik] > system/script/run add-dhcp-no-perms
Added DHCP client on ether2!
Op vergelijkbare wijze zijn er meerdere manieren om een script met de scheduler uit te voeren. Wanneer de scheduler een script uitvoert, kan dit gebeuren met de rechten van de scheduler.
Je kunt het script op naam aanroepen met de scheduler; dit werkt op dezelfde manier als /system script run use-script-permissions.
Om dit te demonstreren maken we drie schedulers aan, die elk zo zijn geconfigureerd dat ze het script op een andere manier uitvoeren:
/system scheduler
add interval=10s name=run-script-use-script-perms on-event="/system script run add-dhcp-no-perms use-script-permissions" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
add interval=10s name=run-script-direct on-event=add-dhcp-no-perms policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
add interval=10s name=run-script-scheduler-perms on-event="/system script run add-dhcp-no-perms" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
Wanneer alle aangemaakte schedulers het script uitvoeren, laten de logs zien dat de twee methoden met use-script-permissions of het aanroepen van het script bij naam mislukken vanwege onvoldoende rechten.
Daarentegen voert run-script-scheduler-perms het script wel met succes uit, omdat het de rechten van de scheduler erft.
/log print
2025-07-22 18:11:25 script,error executing script add-dhcp-no-perms from scheduler (run-script-direct) failed, please check it manually
2025-07-22 18:11:25 script,error,debug not enough permissions (9) (/ip/dhcp-client/add; line 1)
2025-07-22 18:11:25 script,error executing script from scheduler (run-script-use-script-perms) failed, please check it manually
2025-07-22 18:11:25 script,error,debug (scheduler:run-script-use-script-perms) not enough permissions (9) (/ip/dhcp-client/add; line 1)
2025-07-22 18:11:25 system,info dhcp client added by scheduler:run-script-scheduler-perms/script:add-dhcp-no-perms (*7 = /ip dhcp-client add interface=ether2)
Een script met hogere of meer rechten dan de gebruiker/scheduler kan niet worden uitgevoerd; use-script-permissions doet daar niets aan af.