concatenate values to create variable name

My code:

:global $wan1 1;
:put ("wanSta" . $wan1);

return “wanSta1”, my variable is called the same

if I want to set something

:set ("wanStatus" . $wanIndex) 10

returns nothing

search tag # rextended dynamic variables


This:

:global $wan1 1;
:put ("wanSta" . $wan1);
:set ("wanStatus" . $wanIndex) 10

give two errors:
first one because the $ on front of wan1 is forbiden when declaring a global or local variable (I use 6.47.10)
second because the wan1 is undefined on second line for the reason writed before
third on last line you use another name wanStatus

The correct syntax is:

:global wan1 1
:put "wanSta$wan1"
:set wanSta1 10

but obviously do not create or set the variable wanSta1


Short answer:
You can not refer to variables using a result from one operation, but you can use my method:
:global variablename "test"

Create a global variable using the name inside "variablename" and set the value (or update the value if is already defined)

[:parse ":global $variablename "REX1""]

after "parse" the variable exist and can be displayed

:put $test

Set a value of variable with name defined inside "variablename" (or simply apply previous "parse" command)

[:parse "global $variablename;:set $variablename "REX2""]
:put $test

For read the value, of a variable with name defined inside "variablename", and put it inside another global or local declared variable:

:global testx [[:parse ":global $variablename; :return $$variablename"]]
:put $testx

For read the value, of a variable with name defined inside "variablename", simply for put the value on terminal:

:put [[:parse ":global $variablename; :return $$variablename"]]

Or on alternative way: (but this throw an error if the variable not previously created)

:put [/system script environment get $variablename value]
After that the OP script must be:

:global wan1 1
:global variablename "wanSta$wan1"
[:parse ":global $variablename \"10\""]
:put [[:parse ":global $variablename; :return \$$variablename"]]

EDIT: Edited to reflect better OP script

For read the variable inside another declared variable:

:global testx
[:parse “global $variablename;:global testx $$variablename”]

:put $testx

In this example, you output the name of a variable to the value of another variable.

Is it possible to do the opposite? Display the value of a variable in the name of another variable ? And so that it was declared ?

What?

Examples?

Hello,

RouterOS scripting does not support declaring variables which names are taken from another variables value.
Regarding your question, variable is not declared in current scope, that is why you cannot get its value until ;global varname; is added to the script.

Best regards,
Maris B.

If you don’t know the name of the variable anyway, you still can’t manipulate it from the script without declaring it. Therefore, all the fuss with “dynamic variables” loses its meaning.

what are you writing???
who do you answer???
are you explaining to me how my script works???

Indeed, it is impossible to declare a variable with an expression :global $Var, but you can do it via :parse, as in your example above.
But, then it will be possible to access it only through :parse

I experimented a little with your method and realized that dynamic variables can really exist.
You can form their names, assign and extract values without declaring. Here are examples for clarity:

:global variablename "test"

you can create "dynamic variables" whose names are randomly generated and assign values to them

:local name
:for i from=1 to 3 do={
:set name ("$variablename"."$i")
[[:parse ":global $name; set  $name $i"]]
}

After that, the variables test1=1, test2=2 and test3=3 appear in the environment


\

it is possible to extract values from "dynamic variables" as if not knowing their name,

but knowing the algorithm of their formation

:for i from=1 to 3 do={
:set name ("$variablename"."$i")
[[:parse ":global $name; log error (\$$name+5)"]]
}

Everything is fine, but it is not clear why this can be useful in practice ?
Probably in sorting processes ?

So how can you trick code into memory and access it from a Router OS script ?

I’ve never written “trick code into memory” (and I don’t know what you mean by that phrase), so don’t write things that are inaccurate.

Via scripting you can create the script in memory (SCRIPT, not compiled CODE), and then run it,
but if you expect it to write something about it, you will be disappointed, it is an exaggeration, but it is possible to do it.

minimal example on pseudocode:
a = ":put "
b = “hello”
parse (a + b)

I remind you that RouterOS is not a complete programming language, for example it lacks floating point numbers, etc.
You can’t reason with scripts as if it were a programming language.

Remember: you can also use this for get global variable value, not declared before:

:global wan1 1
:global variablename "wanSta$wan1"
[:parse ":global $variablename \"10\""]
# :put [[:parse ":global $variablename; :return \$$variablename"]]
# another  way:
:put [/system script environment get $variablename value]

But if on that case $variablename not exist, throw an error.

Thanks for the tip :slight_smile:

P.S.: Works only with global variables, not for local.

Interestingly, is it possible to run code from a function in this way?

[:parse [/system script environment get $variablename value]]

or

:execute [/system script environment get $variablename value]

Why not?
Try yourself.

I tried. I was unable to execute the function in this way

??? On RouterOS 6.48.6 works.
{
:global test “:log info "ok parse with find"”
:local variablename “test”
[:parse [/system script environment get [find where name=$variablename] value]]
}

{
:global test “:log info "ok execute with find"”
:local variablename “test”
[:execute [/system script environment get [find where name=$variablename] value]]
}

{
:global test “:log info "ok parse directly"”
:local variablename “test”
[:parse [/system script environment get $variablename value]]
}

{
:global test “:log info "ok execute directly"”
:local variablename “test”
[:execute [/system script environment get $variablename value]]
}

It turned out that didn’t work since I tried with :put

Works with log info:

{
:global test ":log info mama"
:local variablename "test"
[:execute [/system script environment get [find where name=$variablename] value]]
}

but it doesn’t work with put:


{
:global test ":put mama"
:local variablename "test"
[:execute [/system script environment get [find where name=$variablename] value]]
}

Do not understand why ?

You need interactive terminal with that script?
Execute execute async on separate thread the script.
execute command do not wait any and the script go immediately to next line of script,
execute is executed separately.
You can not have output on terminal.

[:execute [/system script environment get [find where name=$variablename] value]]

This line is the last one in the script. There’s no one to wait for.

Why it is possible to execute log info and it is impossible to execute :put. It’s not clear.


It doesn’t work that way either:

:global test do={:log info mama}
:local variablename "test"
[[:parse "[/system script environment get [find where name=$variablename] value]"]]

I want to create a myFunc function, even better in a separate script, and call it from another script without using [$myFunc], but using the call through the environment.

This is one function, not one variable where inside is present one string that represent one script for be compared later with parse or execute.
“(eval /log infomessage=mama)” is NOT one script, is [useless] precompiled code.