Community discussions

MikroTik App
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Type "nothing"

Sun Dec 09, 2018 2:36 am

With this code:
:global X1 1
:global type1 [:typeof $X1]
The type of X1 is "num".

But with this other code:
:global i 1
:execute ":global X$i"
:global type2 [:typeof $X1]
The type of X1 is "nothing" instead of "num", with X1 being previously declared as a global variable from other script.

¿Why the nothing type, if X1 already existed?

if you need to know, what I am trying to do is something like this, to reuse several global variables already declared from another script:
:for i from=1 to=4 do={
   :execute ":global IP$i"
}
 
2frogs
Forum Veteran
Forum Veteran
Posts: 713
Joined: Fri Dec 03, 2010 1:38 am

Re: Type "nothing"

Sun Dec 09, 2018 5:52 am

All variables have to be declared that are used in the script, global or not, declared in other scripts or not.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 10:26 am

As 2frogs write, you need to declare it like this.
:global testvarr
If you add something after, you will overwrite current data.

So if in one script you have some like this:
:global testvar "my data"
Then run this in an other script:
:global testvar
:put $testvar
will give
my data
 
User avatar
sebastia
Forum Guru
Forum Guru
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

Re: Type "nothing"

Sun Dec 09, 2018 1:03 pm

The question is why is the typing changing. Declaring a variable shouldn't be doing that.

Tried to replicate, but can't:

2 sessions/terminals

1. run first
[Sebastian@firewall] > :global X1 1
[Sebastian@firewall] > :put [:typeof $X1] 
num

2 run second
[Sebastian@firewall] > {:local i 1; :execute ":global X$i"; :put [:typeof $X1]}       
num
Last edited by sebastia on Sun Dec 09, 2018 1:43 pm, edited 1 time in total.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 1:21 pm

I do not understand your problem. Test this.

First script, storing data
{
:put "storing global variables"
:global text "my text"
:global number 2345
:put "Test of text: $text = $([:typeof $text])"
:put "Test of number: $number = $([:typeof $number])"
}

storing global variables
Test of text: my text = str
Test of number: 2345 = num

Second script, using data
{
:put "using global variables"
:global text
:global number
:put "Test of text: $text = $([:typeof $text])"
:put "Test of number: $number = $([:typeof $number])"
}

using global variables
Test of text: my text = str
Test of number: 2345 = num
Nothing changes, string is str and number is num.


Edit test your script.
admin@941-2nD] > :global X1 123
[admin@941-2nD] >
[admin@941-2nD] > {
{... :local i 1;              # set local variable i=1
{... :execute ":global X$i";  # declare global variable X1, since i=1
{... :put [:typeof $X1];      # Test what type of data X1
{... }
num
[admin@941-2nD] >
[admin@941-2nD] > :global X1 "test"
[admin@941-2nD] >
[admin@941-2nD] > {
{... :local i 1;              # set local variable i=1
{... :execute ":global X$i";  # declare global variable X1, since i=1
{... :put [:typeof $X1];      # Test what type of data X1
{... }
str
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Re: Type "nothing"

Sun Dec 09, 2018 3:13 pm

It works from the terminal but it does not work from a script.
This code in the terminar returns "type=num":
[admin@MK] > {
{... :local i 1;              
{... :execute ":global TrafWAN$i";
{... :global type [:typeof $TrafWAN1];
{... }   
But the same code in a script returns "type=nothing":
:local i 1;
:execute ":global TrafWAN$i";
:global type [:typeof $TrafWAN1];
In both cases the variable $TrafWAN1 already existed as num type and value "123".

Why the same code is being treated differently in the terminal than in the script? Shouldn't be the same?
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 5:06 pm

I do now understand what you try to do.

Declaring global variable works as it suppose to do.
But i fails when you try to declare it indirectly using a variable.
It may be an other way to do it, will test some.
But this seems to be as support case for MT. Send them an email at support@mikrotik.com
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Re: Type "nothing"

Sun Dec 09, 2018 5:12 pm

Thank you Jotne, I will keep on trying different approaches and I will try support@mt as well.
Keep you posted!
 
User avatar
sebastia
Forum Guru
Forum Guru
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

Re: Type "nothing"

Sun Dec 09, 2018 5:12 pm

Maybe it's a case of permissions...

Who has set the original variable? With what permissions?
And what permissions does the script have?

see also viewtopic.php?f=9&t=109696&hilit=script ... permission
Last edited by sebastia on Sun Dec 09, 2018 5:20 pm, edited 2 times in total.
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Re: Type "nothing"

Sun Dec 09, 2018 5:19 pm

Don't think that is the problem, I tried as admin with every policy selected, and same result. Unless the terminal runs the code with different permissions; that, I don't know.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 6:49 pm

Possible solution found.
Do not store you data inn to different global variable, but store all in one global array.

Eks
:global x aa,bb,cc,dd,ee,ff
Script test using indirect variable to get array value.
:local i 2;
:global x
:put [:pick $x $i]
run test
cc
Last edited by Jotne on Sun Dec 09, 2018 7:04 pm, edited 1 time in total.
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Re: Type

Sun Dec 09, 2018 6:57 pm

Mmm, interesting approach! Let me give it a try... Thanks!
Last edited by iperezandres on Mon Dec 10, 2018 1:56 pm, edited 1 time in total.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 7:06 pm

Edit:

You can set a specific field in the array like this:
:set ($myArray->2) 44
Sets 3rd field (fist field=0) to 44

So for example above
:global x aa,bb,cc,dd,ee,ff
Script test
:local i 2
:global x
:put [:pick $x $i]
:set ($x->$i) "QQ"
:put [:pick $x $i]
Result
run test
cc
QQ
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Type "nothing"

Sun Dec 09, 2018 8:26 pm

Even closer to your request
:global x {test1=76;test2=276;test3=387}
/system script> :environment print
x={test1=76; test2=276; test3=387}
script test
:local i 2;
:global x
:put ($x->"test$i")
run test
276
Another example using part of the inner variable with an index
:for a from=1 to=[:len $x] do={:put ($x->"test$a")}
76
276
387
 
Frostbyte
Frequent Visitor
Frequent Visitor
Posts: 92
Joined: Mon Dec 25, 2017 1:42 am

Re: Type "nothing"  [SOLVED]

Fri Dec 28, 2018 12:14 pm

Declaring global variable works as it suppose to do.
But i fails when you try to declare it indirectly using a variable.
Just wanted to chime in on this one.

First, as others already described - you need to declare the variable again (global) in order for your script to "read" it.
If you have a nested function that also uses that variable, you have to re-declare it again inside the nested function as well. (Even if it's declared outside and above it)

The problem begins with the usage of the "execute" command. Execute runs the supplied command in a sub-shell - so you get no interaction with it whatsoever.
Allow me to take it step by step as to what happens here:
:local i 1; <--- local variable "i" is declared with a value of 1, being local means it can only be read by the region it's been put into (script, curly braces, etc).
:execute ":global TrafWAN$i"; <--- $i is resolved into value 1, so the string that's getting executed is ":global TrafWAN1". But this command was ran in a sub-shell, once it completes - POOF! Everything's gone! ..think of it more like calling another script, from your script, to do stuff for you. You cannot interact with it, it only executes whatever is enclosed in its quotes.
:global type [:typeof $TrafWAN1]; <--- the command "typeof" attempts to fetch the type of $TrafWAN1 which at this point hasn't been declared in the script and is therefore "unknown".
The reason this works on the terminal and not on the script, is that on the terminal you can "read" the global variables without having to declare them prior.
Plus, on the terminal version of your code, you can even skip the "execute" line altogether because it offers virtually nothing to you. (it just executes a global declaration and exits)
 
User avatar
iperezandres
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 61
Joined: Mon Feb 13, 2017 1:17 pm
Location: Madrid
Contact:

Re: Type "nothing"

Fri Dec 28, 2018 12:22 pm

Such a good explanation, that was the feeling I was getting from my tests but it is great to have a confirmation.

The thing is that "execute" is a very useful command, even though it has its limitations, and lets you manage code in a dynamically fashion.

Thanks!
Declaring global variable works as it suppose to do.
But i fails when you try to declare it indirectly using a variable.
Just wanted to chime in on this one.

First, as others already described - you need to declare the variable again (global) in order for your script to "read" it.
If you have a nested function that also uses that variable, you have to re-declare it again inside the nested function as well. (Even if it's declared outside and above it)

The problem begins with the usage of the "execute" command. Execute runs the supplied command in a sub-shell - so you get no interaction with it whatsoever.
Allow me to take it step by step as to what happens here:
:local i 1; <--- local variable "i" is declared with a value of 1, being local means it can only be read by the region it's been put into (script, curly braces, etc).
:execute ":global TrafWAN$i"; <--- $i is resolved into value 1, so the string that's getting executed is ":global TrafWAN1". But this command was ran in a sub-shell, once it completes - POOF! Everything's gone! ..think of it more like calling another script, from your script, to do stuff for you. You cannot interact with it, it only executes whatever is enclosed in its quotes.
:global type [:typeof $TrafWAN1]; <--- the command "typeof" attempts to fetch the type of $TrafWAN1 which at this point hasn't been declared in the script and is therefore "unknown".
The reason this works on the terminal and not on the script, is that on the terminal you can "read" the global variables without having to declare them prior.
Plus, on the terminal version of your code, you can even skip the "execute" line altogether because it offers virtually nothing to you. (it just executes a global declaration and exits)

Who is online

Users browsing this forum: No registered users and 22 guests