While writing a small script to be scheduled at regular interval I discovered an anomaly in using global “keyed” (i.e. associative) arrays: according to the available documentation, entire array variables can be assigned with a single set command:
:global MyArray
:set MyArray {a=1; b=2; c=3}
Well, such kind of assignment sometime fails without apparent reason.
Here is a simple script that shows the problem:
:global Y
:if ([:typeof $Y] != "array") do={
:set Y {a=0; b=0; c=0}
:log info ("TEST-SCRIPT: c=$($Y->"c"); global data initialized as $[:typeof $Y]")
} else={
:local count (($Y->"c") + 1)
:set ($Y->"c") $count
:if ($count = 1) do={
:set ($Y->"a") 10
:set ($Y->"b") 11
:log info "TEST-SCRIPT: c=$count; global array assigned"
} else={
:if ($count >= 3) do={
:set Y {a=0; b=0; c=0}
:if (($Y->"c") = 0) do={
:log info "TEST-SCRIPT: c=$count; global array reset OK"
} else={
:log info "TEST-SCRIPT: c=$count; global array reset FAILED"
}
} else={
:log info "TEST-SCRIPT: c=$count; nothing to do"
}
}
}
The above code simulates a script scheduled at regular intervals which uses a global array to store status informations to be passed between different runs. It works as follows:
- each time the script is started it declares the global variable Y
- on the first time the variable was just declared but has no type/value yet, so it is initialized as a “keyed array” with three elements a,b,c (all set to 0); elements “a” and “b” are dummy and are just used to build a multi-element array, while the “c” element will be used as counter and incremented on each subsequent run (1,2,3…)
- on second run (c=1) the elements “a” and “b” are assigned some dummy values (don’t care)
- on third run (c=2) nothing happens (only counter element incremented)
- on fourth and, if the problem arises, subsequent runs (c>=3) the array is reassigned to initial value (all three elements set to 0 in a single command), so on the next run the sequence should restart incrementing c from 0 to 1 (i.e. as in second run above)
Each specific action done by the script is logged, so to be analyzed by looking at the log file.
The problem is that sometimes reassigning the array in step 5 above (i.e. when c=3) fails, so the sequence does not reset and continues with c>3. Here is a partial logfile showing the malfunction:
12:59:21 script,info TEST-SCRIPT: c=0; global data initialized as array
12:59:38 script,info TEST-SCRIPT: c=1; global array assigned
12:59:46 script,info TEST-SCRIPT: c=2; nothing to do
13:00:01 script,info TEST-SCRIPT: c=3; global array reset OK
13:00:08 script,info TEST-SCRIPT: c=1; global array assigned
13:00:09 script,info TEST-SCRIPT: c=2; nothing to do
13:00:11 script,info TEST-SCRIPT: c=3; global array reset FAILED
13:00:22 script,info TEST-SCRIPT: c=4; global array reset FAILED
13:00:23 script,info TEST-SCRIPT: c=5; global array reset FAILED
As you can see the first sequence is correctly restarted but the subsequent one is not.
Additional note: global “keyed array” variables are NOT listed correctly in WinBox (System/Scripts->Environment): value is not shown and not editable. Printing the environment variables from the CLI prompt (/environment print) works as expected.
Reference HW/SW: RB433AH, RouterOS 6.11
Best Regards,
rock