Community discussions

MikroTik App
 
lanhampr
newbie
Topic Author
Posts: 34
Joined: Wed Aug 04, 2021 7:18 pm

Script stops for unknown reason

Mon Dec 11, 2023 11:09 pm

V7.8

I have a script:
/ip dhcp-server {
:local poolname;
:local counter;
:local servername;

:set counter [/ip/dhcp-server/ print count-only] ;
:log info ("Total DHCP Servers: " . $counter);
:set counter ($counter - 1);
#:set counter 5;
:while ($counter) do={
:log info ("Counter: " . $counter);
:set servername [/ip/dhcp-server/ get $counter name];
:log info ("Get: " . $servername);
:set counter ($counter - 1);
:log info ("Done");
}
}

Basically gets total number of DHCP servers then logs the name. I have a total of 6 servers configured, therefore it's 0-5. I can remove the while loop and set counter manually. If I use value 5 for counter the script stops at :set servername [/ip/dhcp-server/ get $counter name]; I get results using counter value of 0-4.

This behavior only happens when I click the Test button or when run via Schedule, it works fine if run from CLI.
 
optio
Long time Member
Long time Member
Posts: 622
Joined: Mon Dec 26, 2022 2:57 pm

Re: Script stops for unknown reason

Tue Dec 12, 2023 12:06 am

Is it working correctly from CLI?
Examine log "Total DHCP Servers: <number>" and number of "Get: <name>" log records, must be same number of log records as number of servers.
When condition operator is not stated while loop stops when variable is false boolean, empty array or 0 (same for any condition statement in script) and that's why is skipping number 0 (doesn't perform iteration for 0). You can just correct this in current script to :while ($counter >= 0) do={
or just use:
/ip/dhcp-server
:foreach server in=[find] do={
  :local servername [get $server name]
  :log info ("Get: " . $servername)
} 
 
lanhampr
newbie
Topic Author
Posts: 34
Joined: Wed Aug 04, 2021 7:18 pm

Re: Script stops for unknown reason

Tue Dec 12, 2023 12:55 am

I saw that but it isn't my issue. I have since modified the sample code:

/ip dhcp-server {
:local poolname;
:local counter;
:local servername;

:set counter [/ip/dhcp-server/ print count-only] ;
:log info ("Total DHCP Servers: " . $counter);
#:set counter 5;
:while ($counter) do={
:set counter ($counter - 1);
:log info ("Counter: " . $counter);
:set servername [/ip/dhcp-server/ get $counter name];
:log info ("Get: " . $servername);
}
:log info ("Done");
}

Here is my environment:
[deeplydigital@cnet-mt-norwoodcnl] /ip/dhcp-server> print
Columns: NAME, INTERFACE, ADDRESS-POOL, LEASE-TIME
# NAME INTERFACE ADDRESS-POOL LEASE-TIME
0 NORWOOD-WIFI sfp-sfpplus2.55 dhcp-norwood-nat-wireless 1h
1 ZHONE-NORWOOD-7 sfp-sfpplus2.7 dhcp-zhone-mgmt 10m
2 ZHONE-NORWOOD-127 sfp-sfpplus2.127 dhcp-zhone-mgmt-alt 10m
3 NORWOOD-WIFI-MANAGEMENT sfp-sfpplus2.1192 dhcp-wifi-mgmt 10m
4 NORWOOD-CGNAT sfp-sfpplus2.60 CGNAT1 5m
5 NATURITA-WIFI sfp-sfpplus2.56 dhcp-naturita-nat-pool 1h
6 NORWOOD-PUBLIC sfp-sfpplus2.40 PUBLIC_pool_1 10m

:set servername [/ip/dhcp-server/ get $counter name] "stops" when $counter is 6, i.e. you won't see command :log info ("Get: " . $servername);
If I set counter to 6, it will show remaining servers, (0-5), without setting counter the only result is :log info ("Counter: " . $counter);
 
optio
Long time Member
Long time Member
Posts: 622
Joined: Mon Dec 26, 2022 2:57 pm

Re: Script stops for unknown reason

Tue Dec 12, 2023 2:03 am

This means in that case [/ip/dhcp-server get 6 name] breaks because of error, maybe "no such item"? Not sure how this can happen if in CLI works but from scheduler or script not on same device, unless is some unexpected behavior when server is dynamically added while this script is performing. Why not try my proposal with find? It's much cleaner.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11937
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script stops for unknown reason

Tue Dec 12, 2023 4:47 pm

The basic problem is that: NUMBERS SHOULD NOT BE USED IN SCRIPTS, which are obtained with "print",
to identify objects, any other opposite assumption is stupid and wrong.

The object ID must be used, not the number 0, 1, 2, etc.

example code

/ip dhcp-server
:local servername  ""
:local poolname    ""
:local dhcpservers [find]
:log info "Total DHCP Servers: $[:len $dhcpservers]"
:foreach item in=$dhcpservers do={
    :set servername [get $item name]
    :set poolname   [get $item address-pool]
    :log info "Servername: $servername - Poolname: $poolname"
}
:log info "Done."
 
lanhampr
newbie
Topic Author
Posts: 34
Joined: Wed Aug 04, 2021 7:18 pm

Re: Script stops for unknown reason

Tue Dec 12, 2023 5:03 pm

A reboot fixed the issue, but thanks for the code to use the object id instead.
 
lanhampr
newbie
Topic Author
Posts: 34
Joined: Wed Aug 04, 2021 7:18 pm

Re: Script stops for unknown reason

Wed Dec 13, 2023 5:58 pm

Here is the full script I was working on. It collects DHCP pool size and remaining IP addresses then sends a JSON payload to a webhook server.

/ip dhcp-server {
:local ip;
:local servertotalips;
:local servertotalleased;
:local nextpool;
:local tmp;
:local poolname;
:local webhook "<webhook URL>";
:local systemname [/system identity get name];
:local json "";
:local debug true;
:local servername;
:local dhcpservers [find]

:log info "Start DHCP Inventory...";
# JSON Payload start...
:set $json "[{\"servername\":\"$systemname\" ,\"dhcp-servers\":{\"entities\":[";

# Log DCHP server total count.
:log info "Total DHCP Servers: $[:len $dhcpservers]"
:foreach item in=$dhcpservers do={
:set servername [get $item name];
:log info ("Get: " . $servername);
:if ($debug) do={:put ("DHCP Server: " . $servername)};

# Get total number of leases for DHCP Server
:set servertotalleased [/ip dhcp-server lease print value-list count-only where server=$servername];
:if ($debug) do={:put ("Total Leased: " . $servertotalleased)}

# Get DHCP Server pool name.
:set poolname [get $item address-pool];

:if ($debug) do={:put ("Pool Name: " . $poolname)}
:if ($poolname = "static-only") do={
:log info ($servername . " No Pool found.")
} else={
#:log info ("Pool Name: " . $poolname);
:set tmp $poolname;

# Get next pool (if exists)
:set nextpool [/ip pool get $tmp next-pool];
#:log info ("Next Pool: " . $nextpool);
# Get pool range
:set ip [:tostr [/ip pool get $poolname ranges]];
#:log info ("IP Range: " . $ip);

# Get total number of pool IP's
:local Start [:pick $ip 0 [:find $ip "-"]];
#:log info ("IP First: " . $Start);
:local Stop [:pick $ip ([:find $ip "-"] + 1) 31];
#:log info ("IP Last: " . $Stop);
:set servertotalips ($Stop - $Start);
#:log info ("IP Range Total: " . $servertotalips);

# Loop thru each DHCP Pool and get an IP Total
:while ([:len $nextpool] != 0) do={
:set ip [:tostr [/ip pool get $nextpool ranges]];

# Get total number of pool IP's
:local Start [:pick $ip 0 [:find $ip "-"]];
:local Stop [:pick $ip ([:find $ip "-"] + 1) 31];
:local pooltotal ($Stop - $Start);

:set servertotalips ($servertotalips + $pooltotal);

:set tmp $nextpool;
:set nextpool [/ip pool get $tmp next-pool];
};

:local available ($servertotalips - $servertotalleased);

:set json ($json . "{\"name\":\"" . $servername . "\",");
:set json ($json . "\"pool-size\":\"" . $servertotalips . "\",");
:set json ($json . "\"available\":\"" . $available . "\"}");
:log info ($servername . " Pool Size: " . $servertotalips . " Available: " . $available);

:set json ($json . ",");
}
}

# Trim last ","
:set json [:pick $json 0 ( [ :len $json ] -1 )];

# Finish JSON Payload
:set json ($json . "]}}]");
:log info $json;
:if ($debug) do={:put ($json)};
# Send webhook
/tool fetch http-method=post http-header-field="Content-Type: application/json" http-data=$json url="$webhook";
}
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3035
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: Script stops for unknown reason

Wed Dec 13, 2023 6:18 pm

FWIW, in 7.13 there is a new ":serialize" command that can take a script array and provide JSON directly. Not suggestion changing, but something to be aware of in future.
 
lanhampr
newbie
Topic Author
Posts: 34
Joined: Wed Aug 04, 2021 7:18 pm

Re: Script stops for unknown reason

Wed Dec 13, 2023 6:55 pm

Thanks! I'll check it out.

Who is online

Users browsing this forum: No registered users and 8 guests