:local i 0;
:local F 0;
:local date;
:local time;
:global InternetStatus;
:global InternetLastChange;
:for i from=1 to=5 do={
\tif ([/ping 8.8.8.8 count=1]=0) do={:set F ($F + 1)}
\t:delay 1;
};
\t\t\t\t
:if (($F=5)) do={
\t:if (($InternetStatus="UP")) do={
\t\t:log info "WARNING : The INTERNET service's gone DOWN";
\t\t:set InternetStatus "DOWN";
##do some action if needed
\t\t:set date [/system clock get date];
\t\t:set time [/system clock get time];
\t\t:set InternetLastChange ($time . " " . $date);
\t\t\t\t
\t} else={:set InternetStatus "DOWN";}
} else={
\t:if (($InternetStatus="DOWN")) do={\t
\t\t:log info "WARNING : The INTERNET service's gone UP";
\t\t:set InternetStatus "UP";
##do some action if needed
\t\t:set date [/system clock get date];
\t\t:set time [/system clock get time];
\t\t:set InternetLastChange ($time . " " . $date);
\t\t\t\t
\t} else={:set InternetStatus "UP";}
Right...Thanks for the correction. Unfortunately there are not many resources about mikrotik scripting language.
While both syntaxes work indeed, I must say that it seems the syntax you call "right" is actually violating normal mode of expression interpolating... making me hope the "right" syntax would be removed in favor of the "wrong" syntax.The syntax
:set variablename valueofthevariable
ARE WRONG,
must be
:set $variablename value=valueofthevariable;
:set not define new variable, like :local or :global, it use already defined variable, and $ must be put before variable name.
Actually it's working for compatibility, but in future version the support for wrong syntax can be removed.
:local varname oldValue :local newvar varname # EXPECTED: # Because the value of $newvar is "varname", # set the variable called "varname" to the value "newValue". :set $newvar newValue # ACTUAL: # Sets the variable "newvar" to the value "newValue", # and keeps "varname" unmodified. :put $varname :put $newvarwould output
newValue
varname
oldValue
newValue
if you use correct syntax you obtain the same::local varname value=oldValue;
--> create new variable called varname and set it's value to string "oldValue"
:local newvar value=varname;
--> create new variable called newvar and set it's value to string "varname"
:set $newvar value=newValue;
--> now set newvar variable content to string "newValue"
:put $varname
--> varname containing "oldValue" and correctly display "oldValue"
:put $newvar
--> newvar containing "newValue" and correctly display "newValue"
How you think to obtain:local varname value=oldValue;
--> create new variable called varname and set it's value to string "oldValue"
:local newvar value=$varname;
--> create new variable called newvar and set it's value equal to variable varname
:set $newvar value=newValue;
--> now set newvar variable content to string "newValue"
:put $varname
--> varname containing "oldValue" and correctly display "oldValue"
:put $newvar
--> newvar containing "newValue" and correctly display "newValue"
Yes, I got that. They indeed obtain the same in current versions.if you use correct syntax you obtain the same:
But see... THAT doesn't make sense... With all other commands, the normal process of interpretation is for:set $newvar value=newValue;
--> now set newvar variable content to string "newValue"
:local interface LAN
/interface monitor-traffic $interface
/interface monitor-traffic interface="LAN"
:local varB $interface
/local name="varB" value="LAN"
:set $varB $interface
/set name="LAN" value="LAN"
/set name="varB" value="LAN"
Neither does it exist in PHP... "variable variables" and "pointers" are two distinct features of a language, and in fact, PHP has the former - see here... In the case of PHP, there's a different syntax required, which can make code confusing, but in RouterOS' scripting language, it's the lack of a different syntax that seems to make things more confusing.The "pointer" type of variable do not exist on that scripting language.
I'll agree that "variable variables" aren't in general a good programming practice, and I for one avoid them in PHP, and would probably avoid them in RouterOS scripting too. But just like any programming tool, they should be available for use if needed, which would arguably be more often in RouterOS scripting that in PHP.And about share same value because one variable is previous set as another variable, I think is the worst way of programming code, without explicit use of pointer.
Now I catch your point...But with "set"... no... that normal flow is broken, and instead ofbeing interpolated toCode: Select all:set $varB $interface
it's suddenlyCode: Select all/set name="LAN" value="LAN"
(really is interpolated to /set name=$varB value="LAN")Code: Select all/set name="varB" value="LAN"
completely flying in the face of how any other command would deal with variables.
[admin@MATRIX] > /set value=k name=x syntax error (line 1 column 19) [admin@MATRIX] > /set value=k name=$x [admin@MATRIX] >because also "/set name=" want as argument one variable, defined or not.
Dear mainTAP,Man, try to read the reply after your previous post !
Ping at least 2 Hosts, and 5 times ping count. If it donot receive all ping replies from both hosts, then its should consider the link DOWN. but if any single host is reachable, then the link should be considered UP.You are welcome, to add more hosts would be easy, how many would you like to check for how many repeats? Do you want to consider the link down only if all the attempts fail?
As for the netwach functionality, i believe it pings just once and makes its decision upon the outcome.
:local i 0;
:local F 0;
:local date;
:local time;
:local webpage1 "8.8.8.8"
:local webpage2 "www.google.com"
:global InternetStatus;
:global InternetLastChange;
:for i from=1 to=5 do={
if ([/ping $webpage1 count=1]=0) do={:set F ($F + 1)}
if ([/ping $webpage2 count=1]=0) do={:set F ($F + 1)}
:delay 1;
};
:if (($F=10)) do={
:if (($InternetStatus="UP")) do={
:log info "WARNING : The INTERNET service's gone DOWN";
:set InternetStatus "DOWN";
## do something
:set date [/system clock get date];
:set time [/system clock get time];
:set InternetLastChange ($time . " " . $date);
} else={:set InternetStatus "DOWN";}
} else={
:if (($InternetStatus="DOWN")) do={
:log info "WARNING : The INTERNET service's gone UP";
:set InternetStatus "UP";
## do something
:set date [/system clock get date];
:set time [/system clock get time];
:set InternetLastChange ($time . " " . $date);
} else={:set InternetStatus "UP";}
}
I am not using google.com, I am using PUBLIC IP addresses for test purpose like isp gateway IP and 8.8.8.8.You can not ping http://www.google.com on script, you must resolve first the DNS to IP...
Is strange: where you have put the script?
I hope new RouterOS version can use dynamically the DNS name instead only IP... ;PThanks for the tip rextended, for some reason it also works with domain name and it resolves the IP automatically