kkgogo
June 29, 2016, 5:21am
1
Hi everyone~ I recently try to do some development with APi,and I got a proboem…
I try to use the api to run a script in the router. It suppose to switch the global variable betwwen “0” and “1”,but it never change.(in the same time,the ":beep "is working)
And it work find If I run the script under telnet or winbox. Can somebody tell me what i have missed ?
Here is the script
:global stat
:if ($stat=1) do={:set $stat 0} else={:set stat 1}
:beep length=1s
What permissions does the API user have?
What permissions does the script have?
Which user is the owner of the script?
We just talked about this in another thread.
Here: http://forum.mikrotik.com/t/global-variables-and-user-permission-policy/99366/1
kkgogo
June 29, 2016, 5:48am
4
script owner is the same as the API user,
and the user is in full group.
Script permissions is all…
Not sure it is important, but the use of $ sign here looks inconsistent.
kkgogo
June 29, 2016, 6:36am
6
.I miss a “blank” after “if” when I typed the code , The script in my router it have a “blank”,so the script is ok.
kkgogo
June 29, 2016, 6:41am
7
Deantwo:
boen_robot:
What about
/set
=name=status
=value=1465304159
(assuming the variable already exists)
or
/global
=name=status
=value=1465304159
(if it doesn’t)
I try the run a script with API and the variable is modify by the script.. not to use api to modify the variable …
The $s are correct, the “if” statment however was missing a space.
This works:
:global stat
{
:if ($stat=1) do={:set $stat 0} else={:set stat 1}
:put $stat
}
Does this mean you got it to work?
EDIT: Guess not.
kkgogo
June 29, 2016, 6:49am
9
script owner is the same as the API user,
and the user is in full group.
Script permissions is all…
The most important thing is I run the script with the same user, telnet is ok,api is not.but the “beep” part is both working.
I went by the title of your thread when I quoted that, sorry.
So are you even sure that the script is even run?
What is the code you use to run the script?
To run a script in one of my API programs I do the following (C# using this ):
public static bool RunScript(string scriptName)
{
bool assumption = false;
MK _mikrotik = new MK(_ip);
if (_mikrotik.Login(_username, _password))
{
string scriptId = null;
_mikrotik.Send("/system/script/print");
_mikrotik.Send("=.proplist=.id");
_mikrotik.Send("?name=" + scriptName);
_mikrotik.Send(".tag=findscript", true);
foreach (string h in _mikrotik.Read())
{
if (h.StartsWith("!done.tag=findscript"))
System.Diagnostics.Debug.WriteLine(h + " *** ACK");
else if (h.StartsWith("!re.tag=findscript"))
{
System.Diagnostics.Debug.WriteLine(h + " *** ACK");
scriptId = h.Substring("!re.tag=findscript=.id=".Length);
}
else
System.Diagnostics.Debug.WriteLine(h);
}
if (String.IsNullOrEmpty(scriptId))
return false;
assumption = true;
_mikrotik.Send("/system/script/run");
_mikrotik.Send("=.id=" + scriptId);
_mikrotik.Send(".tag=runscript", true);
foreach (string h in _mikrotik.Read())
{
if (h.StartsWith("!done.tag=runscript"))
System.Diagnostics.Debug.WriteLine(h + " *** ACK");
else
{
System.Diagnostics.Debug.WriteLine(h);
assumption = false;
}
}
}
_mikrotik.Close();
return assumption;
}
kkgogo
June 29, 2016, 6:52am
11
Deantwo:
The $s are correct, the “if” statment however was missing a space.
This works:
:global stat
{
:if ($stat=1) do={:set $stat 0} else={:set stat 1}
:put $stat
}
Does this mean you got it to work?
EDIT: Guess not.
I have try you code, still can change the variables but the “beep” still work.
How comes the following statements (with and without $) are both correct?
{:set $stat 0}
{:set stat 1}
kkgogo
June 29, 2016, 7:40am
13
with $ or not is the same
I don’t know, but according to the manual and my experience, when you set or define a variable you should not prefix it with a $.
See: http://wiki.mikrotik.com/wiki/Manual:Scripting#Variables
EDIT: Ooh, wait, you are right.
I though you meant that the last one should have a $ too. I blame my killer headache.
:global stat
{
:if ($stat=1) do={:set stat 0} else={:set stat 1}
:put $stat
}
Fixed it, but oddly enough it worked when I pasted it in the console with the $.
And testing it further, it seems to work fine with or without the $.
Despite “$” problem … flipping stat from 0 to 1 and from 1 to 0 could be done as:
:set stat (1-$stat)
Remeber to initalize stat to 0 or 1 in the begining
Ok, Finally got to test it using the API, and I am able to reproduce your issue.
But I have to fiddle a little with users and permissions to test it fully.
Script I am using:
:global stat
{
:if ($stat=1) do={
:set stat 0
:beep length=1
} else={
:set stat 1
:beep length=2
}
}
EDIT: User permissions and script ownership seems to make no difference. The $stat variable’s value will not change.
EDIT2: If I delete the global variable, I can also see that it is not even created when the script is run through the API. Permissions and script ownership again doesn’t seem to matter.
Something as simple as:
:global stat "test"
:log warning $stat
:beep
Seem to fail to actually create the global variable.
Almost as if it is treated as a local variable.
This seems to just fail to run:
:set stat "test"
:log warning $stat
:beep
Even if the global variable exist.
So is there some special permissions that aren’t allowed through the API? Or why would this be blocked.
kkgogo
June 29, 2016, 3:57pm
18
Deantwo:
Something as simple as:
:global stat "test"
:log warning $stat
:beep
Seem to fail to actually create the global variable.
Almost as if it is treated as a local variable.
This seems to just fail to run:
:set stat "test"
:log warning $stat
:beep
Even if the global variable exist.
So is there some special permissions that aren’t allowed through the API? Or why would this be blocked.
Thank you for your testing!
I have done some test too,and I also think it treated that variable as local variable.
Is it a bug ?
colin
April 2, 2018, 2:39pm
19
still have the same problem in ros 6.41.2, hope it will be fixed in the next release.
hsn6
November 23, 2018, 10:10am
20
Hi,
A tested dirty fix should be something like this:
[:execute {:global myglobalvar "myglobalvalue"}]
Another way is to set a scheduler with 1s interval and a line for deleting itself.