Community discussions

MikroTik App
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Global variable works in one script, but not another

Fri Feb 03, 2023 12:07 am

I have a script that has been working for a couple years that pings a few IPs and wrote the results to the log and sends an E-Mail if the pings were excessive.
Last year with help from Rextended (that you sir), the original script was modified so that instead of writing the results to the log, it wrote the results to a couple global variables and passed that to a second script that wrote the results to a file. I did it that way so I could reuse the Write To File script for several similar ping scripts. That also has been working. Then every few hours a third script would send the file via an E-Mail and then reset the log file to 0 bytes. That also has been working fine.
Now I'm trying to add a couple line header to the log file after it is reset to 0 bytes. The easiest way to get the data for that was from a couple of the variables in the original Ping Test script. OK, successfully changed the couple variables from local to global variables and the Ping Test scrip and the Write To File script are working perfectly. The Write to File script does not use the newly created global variables, but the Send the E-Mail script will need them.
The problem is that the E-Mail script is not getting the data from the global variable. As a test, I defined the global variable in the Write To File script and added a log entry of that variable. The correct data was put into the log - so I know the Ping Test script was properly creating the variable as a global. Added the same log entry to the E-Mail script, and it is blank. All three scripts have the same owner and the same permissions - read, write, & test. Here are a couple extracts of the three scripts.

Here the Ping Test script defines the global variables and sets data into them
# Set the monitored IP address and name for test 1
:global ArednIP1 "10.57.166.43";
:global ArednIP1n "W6BI-Shack-Node";

This is the Write To File script where it defines the global variable and write the data in the variable to the log. This works perfectly. What shows up in the log is: 10.57.166.43 - WF script
Note that this was added only for a test, as this script does not need to use the ArednIP1 variable
:global ArednIP1;
:log info "$ArednIP1 - WF script"

This is the E-Mail script where it defines the global variable and write the data in the variable to the log. This fails. What shows up in the log is: - Mail script
:global ArednIP1;
:log info "$ArednIP1 - Mail script"

So why does one work and the other not?
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Global variable works in one script, but not another

Fri Feb 03, 2023 8:01 am

What RouterOS did you test it on?

I did cut and past all data to terminal (winth {} around the code} on a router running 7.6 and all works fine.
.
Code.png

----------------------------------------------------------------------------------------
Use Splunk> to log/monitor your MikroTik Router(s). See link below. :mrgreen:

MikroTik->Splunk
You do not have the required permissions to view the files attached to this post.
Last edited by Jotne on Sun Feb 12, 2023 9:49 pm, edited 1 time in total.
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Global variable works in one script, but not another

Fri Feb 03, 2023 4:33 pm

My error on that. This is on a RB4011GS+ running 6.49.6
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Global variable works in one script, but not another

Mon Feb 06, 2023 12:18 am

Finally had time to post this part.
This is the ping test script that puts all the data together and normally passes a few global variables to the WriteFunction script. This is working correctly. This runs every 5 minutes.
# Ping address and send E-Mail if average RTT exceeds threshold.
# Write results to log file using WriteFunction script

:log info "Starting AREDN ping test."

# Setting up variables.

# Set the monitored IP address and name for test 1
:global ArednIP1 "10.57.166.43";
:global ArednIP1n "W6BI-Shack-Node";

# Set the monitored IP address and name for test 2
:global ArednIP2 "10.108.103.15";
:global ArednIP2n "K6PVR-VC-Camarillo-Hills-SW-5G";

# Set the monitored IP address and name for test 3
:global ArednIP3 "10.98.158.62";
:global ArednIP3n "K6PVR-VC-West-SouthMtn-SE-5G";

# Set the monitored IP address and name for test 4
:global ArednIP4 "10.234.99.239";
:global ArednIP4n "K6PVR-VC-Sulphur-to-Oxnard-5G";

# Set the monitored IP address and name for test 5
:global ArednIP5 "10.162.170.94";
:global ArednIP5n "K6PVR-LA-Verdugo-S-Sector-5G";

# Set the monitored IP address and name for test 6
:global ArednIP6 "10.176.140.239";
:global ArednIP6n "K6ECG-LA-MtWilson-SE";

:log info "Names and IPs set"

# Set the alarm threshhold times in mSec
:local ErrLvl1 100;
:local ErrLvl2 150;
:local ErrLvl3 200;
:local ErrLvl4 200;
:local ErrLvl5 150;
:local ErrLvl6 200;

# Set up variables for average return times
:local AvgRtt1;
:local AvgRtt2;
:local AvgRtt3;
:local AvgRtt4;
:local AvgRtt5;
:local AvgRtt6;

# Set up variables for error E-Mails
:local Sub1 "Excessive AREDN ping time from Router #1."
:local Sub2 "Ping failure to"
:local Sub3 "from Router #1."
:local Bo1 "Test to IP: "
:local Bo2 "Average ping RTT: "
:local Bo3 "Threshhold: "

# Get system date and time
:global datenow [/system clock get date]
:global timenow [/system clock get time];

:log info "Setting data Time header."
:global filename "AREDN_Ping";
:global logthis  "$datenow $timenow"
/system script run "WriteFunction"
:delay 1s

:log info "Starting testing.";
# Start the test for IP 1 - currently not being tested
# /tool flood-ping $Aredn-IP1 count=10 do={
# :if ($sent = 10) do={
# :set AvgRtt1 $"avg-rtt"
#  }}
# :log info "Average RTT to $ArednIP1  $ArednIP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"

:set filename "AREDN_Ping";
# :global logthis  "1: $AvgRtt1 $ErrLvl1"
# temp line below...
:global logthis  "1: Not being tested"
/system script run "WriteFunction"
:delay 1s

# Start the test for IP 2
/tool flood-ping $ArednIP2 count=10 do={
:if ($sent = 10) do={
:set AvgRtt2 $"avg-rtt"
}}
# :log info "Average RTT to $ArednIP2  $ArednIP2n is:  $AvgRtt2  Alarm threshold is:  $ErrLvl2"

:set filename "AREDN_Ping";
:global logthis  "2: $AvgRtt2 $ErrLvl2"
/system script run "WriteFunction"
:delay 1s

# Start the test for IP 3
/tool flood-ping $ArednIP3 count=10 do={
:if ($sent = 10) do={
:set AvgRtt3 $"avg-rtt"
}}
# :log info "Average RTT to $ArednIP3  $ArednIP3n is:  $AvgRtt3  Alarm threshold is:  $ErrLvl3"

:set filename "AREDN_Ping";
:global logthis  "3: $AvgRtt3 $ErrLvl3"
/system script run "WriteFunction"
:delay 1s

# Start the test for IP 4
/tool flood-ping $ArednIP4 count=10 do={
:if ($sent = 10) do={
:set AvgRtt4 $"avg-rtt"
}}
# :log info "Average RTT to $ArednIP4  $ArednIP4n is:  $AvgRtt4  Alarm threshold is:  $ErrLvl4"

:set filename "AREDN_Ping";
:global logthis  "4: $AvgRtt4 $ErrLvl4"
/system script run "WriteFunction"
:delay 1s

# Start the test for IP 5
/tool flood-ping $ArednIP5 count=10 do={
:if ($sent = 10) do={
:set AvgRtt5 $"avg-rtt"
}}
# :log info "Average RTT to $ArednIP5  $ArednIP5n is:  $AvgRtt5  Alarm threshold is:  $ErrLvl5"

:set filename "AREDN_Ping";
:global logthis  "5: $AvgRtt5 $ErrLvl5"
/system script run "WriteFunction"
:delay 1s

# Start the test for IP 6
/tool flood-ping $ArednIP6 count=10 do={
:if ($sent = 10) do={
:set AvgRtt6 $"avg-rtt"
}}
# :log info "Average RTT to $ArednIP6  $ArednIP6n is:  $AvgRtt6  Alarm threshold is:  $ErrLvl6"

:set filename "AREDN_Ping";
:global logthis  "6: $AvgRtt6 $ErrLvl6"
/system script run "WriteFunction"
:delay 1s

# Send E-Mails if Average RTT exceeds threshhold

:if (($AvgRtt1 >= $ErrLvl1) || ($AvgRtt2 >= $ErrLvl2) || ($AvgRtt3 >= $ErrLvl3) || ($AvgRtt4 >= $ErrLvl4) || ($AvgRtt5 >= $ErrLvl5) || ($AvgRtt6 >= $ErrLvl6)) do={
# :log err "Excessive ping time E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=$Sub1 body=("$Bo1 $ArednIP1  $ArednIP1n \n $Bo2 $AvgRtt1 mSec \n $Bo3 $ErrLvl1 mSec \n \n$Bo1 $ArednIP2  $ArednIP2n \n $Bo2 $AvgRtt2 mSec \n $Bo3 $ErrLvl2 mSec \n \n$Bo1 $ArednIP3  $ArednIP3n \n $Bo2 $AvgRtt3 mSec \n $Bo3 $ErrLvl3 mSec \n \n$Bo1 $ArednIP4  $ArednIP4n \n $Bo2 $AvgRtt4 mSec \n $Bo3 $ErrLvl4 mSec \n \n$Bo1 $ArednIP5  $ArednIP5n \n $Bo2 $AvgRtt5 mSec \n $Bo3 $ErrLvl5 mSec \n \n$Bo1 $ArednIP6  $ArednIP6n \n $Bo2 $AvgRtt6 mSec \n $Bo3 $ErrLvl6 mSec")
}

# Send E-Mails if ping failure for test IP 1
:if ($AvgRtt1 = 0) do={
:log err "AREDN Ping failure to $ArednIP1n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP1n $Sub3") body=("$Bo1 $ArednIP1  $ArednIP1n \n $Bo2 $AvgRtt1 mSec")
}

# Send E-Mails if ping failure for test IP 2
:if ($AvgRtt2 = 0) do={
:log err "AREDN Ping failure to $ArednIP2n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP2n $Sub3") body=("$Bo1 $ArednIP2  $ArednIP2n \n $Bo2 $AvgRtt2 mSec")
}

# Send E-Mails if ping failure for test IP 3
:if ($AvgRtt3 = 0) do={
:log err "AREDN Ping failure to $Aredn-IP3n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP3n $Sub3") body=("$Bo1 $ArednIP3  $ArednIP3n \n $Bo2 $AvgRtt3 mSec")
}

# Send E-Mails if ping failure for test IP 4
:if ($AvgRtt4 = 0) do={
:log err "AREDN Ping failure to $ArednIP4n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP4n $Sub3") body=("$Bo1 $ArednIP4  $ArednIP4n \n $Bo2 $AvgRtt4 mSec")
}

# Send E-Mails if ping failure for test IP 5
:if ($AvgRtt5 = 0) do={
:log err "AREDN Ping failure to $ArednIP5n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP5n $Sub3") body=("$Bo1 $ArednIP5  $ArednIP5n \n $Bo2 $AvgRtt5 mSec")
}
# This part currently being ignored
# Send E-Mails if ping failure for test IP 6
# :if ($AvgRtt6 = 0) do={
# :log err "AREDN Ping failure to $ArednIP6n E-Mail is being sent";
# Send mail
# /tool e-mail send to jim@k6ccc.org subject=("$Sub2 $ArednIP6n $Sub3") body=("$Bo1 $ArednIP6  $ArednIP6n \n $Bo2 $AvgRtt6 mSec")
# }

:log info "AREDN ping script completed."

Here is the WriteFunction script with temporarily added declaring the test global variable at the very end and then writing that to the system log. Works perfectly.
# Write to file function for ping tests

:log info "Starting write to file function."

# :global addLogToFile do={
    :global filename
    :global logthis
    :local fileext  ".txt" ; # can be only .txt !!!
    :local maxlen 4095
# :log info "WF line 1"
    /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}
# :log info "WF line 2"
    :local filecon [get $wkfilename contents]
    :local filelen [:len $filecon]
    :local addthis "$logthis\r\n"
# :log info "WF line 3   $addthis"
    :local addlen  [:len $addthis]
# :log info "WF line 4"
    :if (($filelen + $addlen) > $maxlen) do={
        :set filecon ""
        :set filelen 0
        :delay 1s
    }
# :log info "WF line 5"
    :set filecon "$filecon$addthis"
    set $wkfilename contents=$filecon
    :delay 1s
# }

# This added only to test global ArednIP1 for E-Mail script.  This works correctly.
:global ArednIP1;
:log info "$ArednIP1 - WF script"

Lastly, this is the Mail the file created by the WriteFunction script. This runs every 3 hours.
# Policies needed:  ftp, read, write
# Policies NOT needed:  ftp, policy, sensitive, dude, password, reboot, sniff, romon

# As a test, I added the log as soon at the global variable was declared - just in case the script itself was messing it up.
# All that goes into the log is   - Mail script
:global ArednIP1;
:log info "$ArednIP1 - Mail script"

:global ArednIP2;
:global ArednIP3;
:global ArednIP4;
:global ArednIP5;
:global ArednIP6;
:local filecon;

:log info "setup comp"

/tool e-mail send file=AREDN_Ping.txt to="jim@k6ccc.org" body="AREDN Ping test results file attached." \
  subject="AREDN Ping tests  $[/system clock get date] at $[/system clock get time]"
:delay 00:00:05
/file
set AREDN_Ping.txt contents=""
# The above line correctly deletes the contents of the AREDN_Ping.txt file

:delay 00:00:01

:log info $ArednIP1
set AREDN_Ping.txt contents="$ArednIP1"

# this part remarked out while troubleshooting.  There will be a total of 6 lines of text added to the file.
# :set filecon [get "AREDN_Ping.txt" contents]
# :set filecon "$filecon$ArednIP1"
# set AREDN_Ping.txt contents="$filecon"

:log info "Mail AREDN Pings script completed"
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Global variable works in one script, but not another

Mon Feb 06, 2023 11:59 am

# Policies needed: ftp
# Policies NOT needed: ftp
Make a decision :P

When I have time I check this, Is needed time to review all.
Some lines.... are familiar :lol:
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Global variable works in one script, but not another

Mon Feb 06, 2023 7:37 pm

# Policies needed: ftp
# Policies NOT needed: ftp
Make a decision :P
That's just a remark I put at the top of most of my scripts. Supposed to be read, write, & test. The actual permissions were correct, just my remark at the top had it wrong... Fixed
When I have time I check this, Is needed time to review all.
Some lines.... are familiar :lol:
Should be - you wrote a good portion of it...
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Global variable works in one script, but not another

Mon Feb 06, 2023 8:15 pm

# Policies needed: ftp
# Policies NOT needed: ftp
Make a decision :P
That's just a remark […] Fixed
Sorry, is just a joke!!! :P
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Global variable works in one script, but not another

Sun Feb 12, 2023 9:53 pm

I have been poking at this and may be onto something. Don't have the resolution, but I'm down the right road - I think. Scopes.
The "AREDN ping test" script is started from the Scheduler.
The "WriteFunction" script is called from the "AREDN ping test" script - the global works
The "Mail AREDN Pings" script is started from the Scheduler - the global does not work.

As a test, I called the "Mail AREDN Pings" script from the "AREDN ping test" script - this time the global worked in the "Mail AREDN Pings" script.

So, it would appear that the global variable is still being limited by a scope. Does this seem to be a reasonable assumption? And how do I make the global variable truly global - or some other work around?
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Global variable works in one script, but not another

Mon Feb 13, 2023 3:40 am

Success. I changed my concept a bit. Now, at the end of the "AREDN ping test", it checks the size of the "AREDN_Ping.txt" file. If that file size exceeds 3900 bytes, it then calls the "Mail AREDN Pings" script. That apparently keeps the global variables in scope and it works.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Global variable works in one script, but not another

Mon Feb 13, 2023 10:48 am

Use this as example, when you do multiple times same thing on scripts, better use cycles...
:log info "Starting AREDN ping test."

:local arrIP  [:toarray "10.57.166.43,10.108.103.15,10.98.158.62,10.234.99.239,10.162.170.94,10.176.140.239"]
:local arrIPn [:toarray "W6BI-Shack-Node,K6PVR-VC-Camarillo-Hills-SW-5G,K6PVR-VC-West-SouthMtn-SE-5G,\
    K6PVR-VC-Sulphur-to-Oxnard-5G,K6PVR-LA-Verdugo-S-Sector-5G,K6ECG-LA-MtWilson-SE"]
:local arrIPe [:toarray "100,150,200,200,150,200"]
:global AvgRtt [:toarray ""]

:log info "Names and IPs set"

:local Sub1 "Excessive AREDN ping time from Router #1."
:local Sub2 "Ping failure to"
:local Sub3 "from Router #1."
:local Bo1  "Test to IP: "
:local Bo2  "Average ping RTT: "
:local Bo3  "Threshhold: "

/system clock
:local datenow [get date]
:local timenow [get time]

:log info "Setting data Time header."
:global filename "AREDN_Ping"
:global logthis  "$datenow $timenow"
/system script run "WriteFunction"
:delay 1s

:log info "Starting testing."

:global logthis  "1: Not being tested"
/system script run "WriteFunction"
:delay 1s

:for item from=0 to=([:len arrIP] - 1) step=1 do={
    /tool flood-ping ($arrIP->$item) count=10 do={:if ($sent = 10) do={:set ($AvgRtt->$item) $"avg-rtt"}}
    :global logthis "$item: $($AvgRtt->$item) ($arrIPe->$item)"; /system script run "WriteFunction"; :delay 1s
    :if (($AvgRtt->$item) = 0) do={
        :log err "AREDN Ping failure to $($arrIPn->$item) E-Mail is being sent"
        /tool e-mail send to="jim@k6ccc.org" subject=("$Sub2 $($arrIPn->$item) $Sub3") \
            body=("$Bo1 $($arrIP->$item) $($arrIPn->$item) \n $Bo2 $($AvgRtt->$item) mSec")
    }
    :if (($AvgRtt->$item) >= ($arrIPe->$item)) do={
        /tool e-mail send to="jim@k6ccc.org" subject=$Sub1 \
            body=("$Bo1 $($arrIPn->$item)  $($arrIPn->$item) \n $Bo2 $($AvgRtt->$item) mSec \n $Bo3 $($arrIPe->$item) mSec")
    }
}

:log info "AREDN ping script completed."

Who is online

Users browsing this forum: No registered users and 14 guests