Page 1 of 1

Unique Global Variables

Posted: Thu Jul 31, 2014 11:00 pm
by marrold
Hi all,

I've been scripting now for coming up to a year and I am now managing several Mikrotik devices. To simplify management, I am re-writing scripts and improving them, with a view that only a handful of variables need updating at the top of the script for each location, and the rest can be left as is.

There are a few scenarios where I have to persistently store information in a Global Variable, like an interface IP address. The problem comes when I have several copies of the same script running simultaneously (E.G for several interfaces). The Global Variables then clash if they are not individually named manually.

Is there anyway I can have unique global variables per script?

Any ideas are appreciated.

Re: Unique Global Variables

Posted: Thu Jul 31, 2014 11:09 pm
by boen_robot
AFAIK, no... Other than, obviously, that you prefix the name with the value of another variable (e.g. the interface name) upon declaration.

To make this easier on yourself, you should pack your scripts into a function variable (you know... the "do" argument on ":global"...), and then use that function. The function itself will "install" each instance, i.e. declare the per-script global variables, their initial values, and perhaps add itself to scheduler if needed to keep them updated.


BTW, if you end up making some "general purpose" scripts (i.e. ones that let a user define their own settings, rather than use your hardcoded ones), abstracted away as functions, I'm sure many people (myself included) would like to check them out, so if you could share, that would be awesome.

Re: Unique Global Variables

Posted: Thu Jul 31, 2014 11:36 pm
by marrold
AFAIK, no... Other than, obviously, that you prefix the name with the value of another variable (e.g. the interface name) upon declaration.
Thats the method I am using at the moment.
To make this easier on yourself, you should pack your scripts into a function variable (you know... the "do" argument on ":global"...), and then use that function. The function itself will "install" each instance, i.e. declare the per-script global variables, their initial values, and perhaps add itself to scheduler if needed to keep them updated.
I dont quite understand sorry. Do you mean a script to 'install' the script?

Thanks for your input

Re: Unique Global Variables

Posted: Fri Aug 01, 2014 12:10 am
by psamsig
If the variables is only used within a script, they should be declared local and not global.

Re: Unique Global Variables

Posted: Fri Aug 01, 2014 12:18 am
by marrold
If the variables is only used within a script, they should be declared local and not global.
The variables need to be stored persistently, I.E if the script is run again, the variables are still there. Local variables only apply in that instance the script is ran.

Re: Unique Global Variables

Posted: Fri Aug 01, 2014 12:22 am
by boen_robot
To make this easier on yourself, you should pack your scripts into a function variable (you know... the "do" argument on ":global"...), and then use that function. The function itself will "install" each instance, i.e. declare the per-script global variables, their initial values, and perhaps add itself to scheduler if needed to keep them updated.
I dont quite understand sorry. Do you mean a script to 'install' the script?
Yes.

The idea is that you won't have to "manually" enter new global variables for each copy of the script, but you'll instead run the script with parameters. The parameters will determine the variables to be added, and add a copy of the script that would use those variables.

So for example,
$installMonitor interface=local
Would read the "interface" argument, and create a global variable with the name "monitor_local_ip" for the IP address of the interface "local", and so on. If you want the same script for another interface, you run your install script with the name of the new interface, so
$installMonitor interface=wan1
to now create the "monitor_wan1_ip" variable, etc.

Re: Unique Global Variables

Posted: Fri Apr 10, 2015 1:34 pm
by dissident76
To make this easier on yourself, you should pack your scripts into a function variable (you know... the "do" argument on ":global"...), and then use that function. The function itself will "install" each instance, i.e. declare the per-script global variables, their initial values, and perhaps add itself to scheduler if needed to keep them updated.
I dont quite understand sorry. Do you mean a script to 'install' the script?
Yes.

The idea is that you won't have to "manually" enter new global variables for each copy of the script, but you'll instead run the script with parameters. The parameters will determine the variables to be added, and add a copy of the script that would use those variables.

So for example,
$installMonitor interface=local
Would read the "interface" argument, and create a global variable with the name "monitor_local_ip" for the IP address of the interface "local", and so on. If you want the same script for another interface, you run your install script with the name of the new interface, so
$installMonitor interface=wan1
to now create the "monitor_wan1_ip" variable, etc.
Hi robot,

That is exactly the idea I was looking for, but what's the syntax to use the value of a parameter (or variable) as variable name?
I have tried this and it does not work:
:global name wan1;
:global $name
If this worked, I would have declared a variable named "wan1", which is the value of $name (or any parameter, like $1, etc)

Thanks a lot

Re: Unique Global Variables

Posted: Fri Apr 10, 2015 2:17 pm
by noib
Dirty way to have system-wide, persistent variable even after reboot: use something like a comment on an interface.
/interface ethernet set ether1 comment=$myData
:local myData [/interface ethernet get ether1 comment ];

Re: Unique Global Variables

Posted: Fri Apr 10, 2015 3:19 pm
by boen_robot
Drat... I thought that the syntax would be
:global name="$interface" "value";
(with the "name=" and quotes being a way to disambiguate between that and a new global variable called "interface")
But that doesn't work... The only way seems to be to call :execute with appropriate arguments, which BTW means the installer can be easily broken when a value is supplied that would spill into the rest of the script (probably causing a had to detect error).

So f.e.
:execute script=":global \"interface_$interface\" \"val\""
would create a global variable with a name equal to "interface_", followed by the interface name, and with a value equal to "val". If $interface had a value of "local", the variable can then be referenced with $"interface_local".

Re: Unique Global Variables

Posted: Fri Apr 10, 2015 6:59 pm
by dissident76
Drat... I thought that the syntax would be
:global name="$interface" "value";
(with the "name=" and quotes being a way to disambiguate between that and a new global variable called "interface")
But that doesn't work... The only way seems to be to call :execute with appropriate arguments, which BTW means the installer can be easily broken when a value is supplied that would spill into the rest of the script (probably causing a had to detect error).

So f.e.
:execute script=":global \"interface_$interface\" \"val\""
would create a global variable with a name equal to "interface_", followed by the interface name, and with a value equal to "val". If $interface had a value of "local", the variable can then be referenced with $"interface_local".
Yeah, that worked, thanks a lot :)