Community discussions

MikroTik App
 
heves
just joined
Topic Author
Posts: 4
Joined: Wed Aug 03, 2022 10:42 pm

Script fails to create file

Mon Aug 08, 2022 8:54 pm

I want to save the number of connected users for each of my wireless interfaces using a script. However, it would seem I messed something up, because it's not working.

Here is my code, I did some testing and it seems the code gets stuck in an infinite loop inside the "foreach", on the "else" branch. For some reason, the file just doesn't get created.

:global ifLastSaved

:local time [:pick [/system/clock/get time] 0 5]
:local day [:pick [/system/clock/get date] 4 6]
:local interfaces "12.1_5g,12.1_ch1,12.2_ch1,12.3_ch6,12.4_ch11,12.5_ch11"
:local ifArr [:toarray $interfaces]

#initialize save time
:if ([:len $ifLastSaved]=0) do={ :set $ifLastSaved [:pick $time 0 2]};

:foreach if in=$ifArr do={

	:local data ($time." ".[:len [/caps-man registration-table find interface=$if]])
	
	:local filename ("resziget/" . $if . "/" . $if . "-" . [:pick [/system/clock/get date] 4 6])
	
	#we have to create a new file every few hours because of the 4096 character limit
	:if ([:pick $time 0 2] > $ifLastSaved +2) do={
		:set $ifLastSaved [:pick $time 0 2]		
		:set $filename ($filename . "-" . [:pick $time 0 2])
		/file print file=$filename
		:while ([:len [/file/find name=$filename]] = 0) do={ :delay 100ms }
		/file set $filename contents=""
	} else={
		:set $filename ($filename . "-" . $ifLastSaved)
		:if ([:len [/file/find name=$filename]] = 0) do={
			/file print file=$filename
			:while ([:len [/file/find name=$filename]] = 0) do={ :delay 100ms }
		}
	}

	#this part returns "no such item"
	/file set $filename contents=([get $filename contents] . $data)

};

If anyone could point out why this happens and how can I fix it, I would be really thankful. I've spent the last few hours testing and tweaking the code and I just can't seem to make any progress.

Edit: I want to run a scheduler with this script. This script would iterate over my CAPs interfaces and extract the number of connected clients from each one. Then it would put the information in a file. We'd add new info at the end of the file for a while (3 hours currently), then we'd create a new file because of the 4096 character limit I heard about. For some reason, the file creation fails. The while-delay loops are supposed to prevent attempting to set a file before it is created. I tried without them, but that also doesn't seem to work.
Last edited by heves on Tue Aug 09, 2022 4:17 am, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script fails to create file

Mon Aug 08, 2022 9:29 pm

Better you describe what you want, instead to ask where is the error.....
 
heves
just joined
Topic Author
Posts: 4
Joined: Wed Aug 03, 2022 10:42 pm

Re: Script fails to create file

Tue Aug 09, 2022 11:16 am

Better you describe what you want, instead to ask where is the error.....
You are right, sorry. I edited the original post to include the intended functionality.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script fails to create file

Tue Aug 09, 2022 2:15 pm

First step must be create a routine for everything, not only the cap, that create a file,
and backup the contents automatically before adding the new log line go over the max (that is 4095, not 4096).
On reboot is resumed last file.
If the device have Flash, not NAND, the file is created accordingly.
{
:local filename "caphistory"
:local fileext  ".txt" ; # can be only .txt !!!

:global arrMonths {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12"}

/system clock
:local ndate  [get date]
:local ntime  [get time]
:local fdname "$[:pick $ndate 7 11]$($arrMonths->[:pick $ndate 0 3])$[:pick $ndate 4 6]$[:pick $ntime 0 2]$[:pick $ntime 3 5]"
:local isonow "$[:pick $ndate 7 11]-$($arrMonths->[:pick $ndate 0 3])-$[:pick $ndate 4 6] $ntime"
:local maxlen 4095

/file
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
:local wkfilename "$filename$fileext"
:if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
:local bkfilename "$filename-$fdname$fileext"

:local filecon [get $wkfilename contents]
:local filelen [:len $filecon]

:local addthis "$isonow: ***test***\r\n"

:local addlen  [:len $addthis]

:if (($filelen + $addlen) > $maxlen) do={
    print file=$bkfilename
    :delay 2s
    set $bkfilename contents=$filecon
    :set filecon ""
    :set filelen 0
}

:set filecon  "$filecon$addthis"
set $wkfilename contents=$filecon
:delay 1s
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script fails to create file

Tue Aug 09, 2022 2:34 pm

2nd step is create a function
:global arrMonths {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12"}
:global addLogToFile do={
:local filename "$1"
:local fileext  ".txt"
/system clock
:local ndate  [get date]
:local ntime  [get time]
:local fdname "$[:pick $ndate 7 11]$($arrMonths->[:pick $ndate 0 3])$[:pick $ndate 4 6]$[:pick $ntime 0 2]$[:pick $ntime 3 5]"
:local isonow "$[:pick $ndate 7 11]-$($arrMonths->[:pick $ndate 0 3])-$[:pick $ndate 4 6] $ntime"
:local maxlen 4095
/file
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
:local wkfilename "$filename$fileext"
:if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
:local bkfilename "$filename-$fdname$fileext"
:local filecon [get $wkfilename contents]
:local filelen [:len $filecon]
:local addthis "$isonow: $2\r\n"
:local addlen  [:len $addthis]
:if (($filelen + $addlen) > $maxlen) do={
    print file=$bkfilename
    :delay 2s
    set $bkfilename contents=$filecon
    :set filecon ""
    :set filelen 0
}
:set filecon  "$filecon$addthis"
set $wkfilename contents=$filecon
:delay 1s
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script fails to create file

Tue Aug 09, 2022 2:42 pm

Do not work on SMIPS. (for work on SMIPS, manually create the directory structure and commend the smb lines)

3rd step visualizing what is wanted inside the file, and create directory tree:
{
:local interfaces "12.1_5g,12.1_ch1,12.2_ch1,12.3_ch6,12.4_ch11,12.5_ch11"
:local parentdir  "resziget" 

/file
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set parentdir "flash/$parentdir"}

/ip smb shares remove [find where name="temp"]
/ip smb shares add name="temp" directory=$parentdir

:foreach item in=[:toarray $interfaces] do={
    /ip smb shares remove [find where name="temp"]
    /ip smb shares add name=temp directory="$parentdir/$item"
    :local fname "$parentdir/$item/$item"
    :local logtx [:len [/caps-man registration-table find where interface=$item]]
    :put "file name: \"$fname.txt\" - add this content: \"<DATE> <TIME>: $logtx\""
}

/ip smb shares remove [find where name="temp"]
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script fails to create file

Tue Aug 09, 2022 2:46 pm

Do not work on SMIPS. (for work on SMIPS, manually create the directory structure and commend the smb lines)

last step, join data & functions and test:
:global arrMonths {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12"}
:global addLogToFile do={
:local filename "$1"
:local fileext  ".txt"
/system clock
:local ndate  [get date]
:local ntime  [get time]
:local fdname "$[:pick $ndate 7 11]$($arrMonths->[:pick $ndate 0 3])$[:pick $ndate 4 6]$[:pick $ntime 0 2]$[:pick $ntime 3 5]"
:local isonow "$[:pick $ndate 7 11]-$($arrMonths->[:pick $ndate 0 3])-$[:pick $ndate 4 6] $ntime"
:local maxlen 4095
/file
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
:local wkfilename "$filename$fileext"
:if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
:local bkfilename "$filename-$fdname$fileext"
:local filecon [get $wkfilename contents]
:local filelen [:len $filecon]
:local addthis "$isonow: $2\r\n"
:local addlen  [:len $addthis]
:if (($filelen + $addlen) > $maxlen) do={
    print file=$bkfilename
    :delay 2s
    set $bkfilename contents=$filecon
    :set filecon ""
    :set filelen 0
}
:set filecon  "$filecon$addthis"
set $wkfilename contents=$filecon
:delay 1s
}

{
:local interfaces "12.1_5g,12.1_ch1,12.2_ch1,12.3_ch6,12.4_ch11,12.5_ch11"
:local parentdir  "resziget" 

/file
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set parentdir "flash/$parentdir"}

/ip smb shares remove [find where name="temp"]
/ip smb shares add name="temp" directory=$parentdir

:foreach item in=[:toarray $interfaces] do={
    /ip smb shares remove [find where name="temp"]
    /ip smb shares add name=temp directory="$parentdir/$item"
    :local fname "$parentdir/$item/$item"
    :local logtx [:len [/caps-man registration-table find where interface=$item]]
#    :put "file name: \"$fname.txt\" - add this content: \"<DATE> <TIME>: $logtx\""
    [$addLogToFile $fname $logtx]
}

/ip smb shares remove [find where name="temp"]
}

Who is online

Users browsing this forum: No registered users and 20 guests