Baffled by global variable behavior in scripting

Context: CCR2004 running ROS 7.15.3, logged in via WinBox as an admin.

I’m a senior C++ engineer of many years, so language quirks and oddities are not unknown to me, but I’m struggling to understand this behavior.

I have a script that writes to a couple global variables.

For a long time I’ve been frustrated by the strange handling of globals in ROS scripts. It seems sometimes they read/write, and other times they don’t. I finally got so annoyed I troubleshot the problem.

I have “read” and “write” policies set on the script. This makes sense as global variables need to be stored in and read from the environment list.

For some reason, the “policy” and “test” policies are the difference between writing data to a global variable and not. I fail to comprehend how this relates. Yet if I remove either (or both) from my script, the globals are neither created, nor written to. Add them back in, and like magic the globals are created and given a value.

Additionally odd is it cannot even read an existing global directly, but can if I use the convoluted [/system/script/environment/get [/system/script/environment/find name=“variablename”] value]

Can anyone explain this?

I can reproduce this behavior with a script as simple as:

:global testingvar1
:global testingvar2

:global testingvar1 "text"
:global testingvar2 0.0.0.0/0

:log info ("Test has run.")



  1. Uncheck all policies, and add in “read” and “write”. Run. Check the environment list. Won’t be listed.
  2. Add any combination of policies that are not both “policy” and “test”. Run. Check the environment list. Won’t be listed.
  3. Have “Read”, “Write”, “Policy” and “Test” checked. Run. Check the environment list. There are the variables.

Mikrotik gurus, help me wrap my head around this, please!

It’s just odd. But this is the documented behavior for recent versions:

policy - policy that grants user management rights. Should be used together with the write policy. Allows also to see global variables created by other users (requires also ‘test’ policy).

(from https://help.mikrotik.com/docs/display/ROS/User#User-UserGroups )

Now :global used be “more global” in previous versions. But there were a series of various “privilege escalation” bugs with scripting that prompt the change to require “policy” (and “test”) as a script policy. Gist is a user with write privilege could create/run a script with greater policies assigned in certain cases. e.g. if globals stored some API key or password or whatnot, a less privileged user could read it. The complexities get worse if you use script in other context, like /tool/netwatch’s on-up/on-down, as there are even more restrictions. In general, these are all documented, but the info is spread across several help topics.

On this point…

Additionally odd is it cannot even read an existing global directly, but can if I use the convoluted [/system/script/environment/get [/system/script/environment/find name=“variablename”] value]

Certainly there is argument that your convoluted example falls into same “privilege escalation” bug category since you should, per docs, need those policies… The underlying issue is that the policy system is just not very rich, or granular, or even coherent. So Mikrotik just patches the existing policy system to handle these “oddities” as they come up.

So you got fair complaint here. But you need “test” and “policy” as it is designed to use globals.