why do global vars not work?

:global gVar
:log info "gVar= $gVar"
:log info "Why is above blank after it was run once?"
:set gVar "something"
:log info "gVar= $gVar"

Why doesn’t “something” end up in my global var after I’ve run this script once (never mind multiple times)???

globalvarnotworking.png

Globals have to be defined in top-level scope. At the CLI, the code does what you expect.

[removed confusing example]

All code run in terminal needs to be in one block. You hva two option to do that.

  1. Use bracket like this:
{
:global gVar 
:log info "gVar= $gVar"
:log info "Why is above blank after it was run once?"
:set gVar "something"
:log info "gVar= $gVar"
}
  1. Have all commands in one line with commands separated by ;
:global gVar ; :log info "gVar= $gVar" ; :log info "Why is above blank after it was run once?" ; :set gVar "something" ; :log info "gVar= $gVar"

In a normal saved script, your code works fine without {}.

Why did you write it like that, if you define the variable after, it’s not retroactive…


I don’t know what other script exists on your device or the version of RouterOS v7.x (architecture?) you use, but for me everything works as expected on v7.7 arm64

The other users’ answers are irrelevant, not because they’re wrong, but because you phrased your question so badly that it’s misunderstood.

Don’t be rude, reply to users who reply to you instead of ignoring them.

Except when is never used one “:local” variable.

Can be defined any time… but…
:if (true) do={:global outx “OK”}
:put $outx

this work because the new line, on terminal, is another context that find already defined globally “outx”

using { } prevent the “test1” working…

{
:global test2
:if (true) do={:global test1 “OK”}
:if (true) do={:global test2 “OK”}

inside test1 do not work because is not definded before, no matter if is anywhere or on this context.

:put “inside test1 $test1”
:put “inside test2 $test2”
}

but outside, on another context work because is defined…

:put “outside test1 $test1”
:put “outside test2 $test2”

the “:local” are never available out of context, no matter the { }

{
:local test4
:if (true) do={:local test3 “OK”}
:if (true) do={:local test4 “OK”}
:put “inside test3 $test3”
:put “inside test4 $test4”
}
:put “outside test3 $test3”
:put “outside test4 $test4”

But if they are defined in a block (e.g. between curly braces { } ) they won’t become global

but… see upper example.

An :if statement is still top-level scope. I should have been clear it’s not just {}.

The issue is what’s causing the difference between the OP’s code and the results in the screenshot. The context of the snippet matters, since as posted, it works…

If the :global was really set, there should only be one blank result the first time it’s run.

I have integrated some description on previous post…

On v7.6 and previous (only v7) there is present one bug that cause disappearing of global variables,
(see my post on release topic)
is why is important specify both RouterOS version and platform.

Yup, I tried on v7.8 and v6.49. OP screenshot did show there was some issue...

I mainly use V7... I'm not sure how far back your bug goes, I really don't recall running into it. But then again I don't have use a lot of long duration globals, mainly functions - possible I'd miss it.

Am running 6.48.

Tried the following and the script won’t run at all. A syntax error, I guess?

{
:global gVar
}
:log info "gVar= $gVar"
:log info "Why is above blank after it was run once?"
:set gVar "something"
:log info "gVar= $gVar"

The following runs okay but I get the same result - the global variable is forgotten/cleared after the script ends.

{
:global gVar
:log info "gVar= $gVar"
:log info "Why is above blank after it was run once?"
:set gVar "something"
:log info "gVar= $gVar"
}

Maybe I’ll try upgrading to latest version of 7.x.

Alternatively, how else can I save data and recall it next time I run the script? I’ve not done a lot of scripting at this point, and have not had to use global/persistent data until now.

Who did tell you to put only :global gVar in brackets?
For a script to run, its not needed to use {}
Only when copy paste to cli, then the whole block needs to be in {}

PS it will be blank at first run, since it has not stored any thing in its memory, so that is normal operation.

Tested on a 6.49.9 router working fine, so this should work on 6.48 as well.

Red first run, green second run.
Cli only sown script once, since I just used arrow up and enter to run it a second time.
.
script.png

My bad example is why.

But a :global at CLI should NOT need brackets for the above code. The first time it’s run, the first log should be blank since it isn’t initialized, that be expected. But once the :set had been called, that’s the value that should be available without brackets in future.

Here is v7.8, on a RB1100AHx4 (arm), using the OP’s original code:

Under V6, the ? will have to be escaped. But also works. I can open a new terminal in both cases in and just do a :put $gVar and it works (once it was :set someplace). V6 test MMIPS-based hEX S with 6.49.7.

Maybe try 6.49.7 “stable” first, less invasive of a change than going to V7 to fix scripting. Since this should work, the only alternative is storing it a file or store someplace in the config itself (e.g. a comment) but both approaches are kinda hackish and more code each time than a simple :global to load/set.

I use 6.48.6 and it work as expected, not needed to go to 6.49.x or v7

Usually following happens when work with global variables.
When you test to print global variable in CLI, it works. But somehow exact same in the script doesn’t work. Even you can see that variable is clearly set in the scripting environment.
This is because, when we read global variable inside the script, we need to declare it on top of the script.

It really makes a lot of sense to reply to such an old post…
It seems like one of the banal AI responses just to write something… Write write, and then there is no sense or anything new…