Using a script variable as a script command.

Hi guys,

Back with another script-related query today :slight_smile:

Trying to write a section of code that will allow me to take a variable and allow it to be inserted (or not inserted) as part of an ‘add’ command on a RouterOS device.

Example:

/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254

vs

/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-local-pref=1111

I want to be able to run this command from inside a script, which in itself is easy enough, however the “src-address” value (or other values) should only be included if they exist.

The way I’m trying to do this currently works like so, I read/define each value throughout the script then when I get to the add command I use all of these values at once like so

/ip route add dst-address=$dstaddress gateway=$gateway bgp-local-pref=$bgplocalpref

which then gives me an error as although I can enter a blank value for bgp-local-pref in a terminal window, having it do so from a script causes an error.

admin@MikroTik] > ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-local-pref=
[admin@MikroTik] > system script run test                                                       
invalid value  for bgp-local-pref, an integer required
[admin@MikroTik] >

As you can see, the terminal accepts no value fine.. while the test script (listed below) causes an error.

:local dstaddress "192.168.1.0/24" 
:local gateway "192.168.0.254"
:local bgplocalpref

/ip route add dst-address=$dstaddress gateway=$gateway bgp-local-pref=$bgplocalpref

So, I figure.. why not just check if the value exists at all and if not don’t call it as part of the command.

/ip route add dst-address=$dstaddress gateway=$gateway [:if ([:len $bgplocalpref] > 0 ) do={bgp-local-pref=$bgplocalpref}]

However this doesn’t work either. Now it would be easy enough to just write 2 /ip route add statements based on bgp-local-pref however I’m actually trying to work with a number of the bgp values so for each value I’d be required to write a number more /ip route add statements (for 5 attributes, 32 statements are required).

So.. I went for an alternative solution: set the values to be part of the command as well.

:if ([:len $bgplocalpref] > 0 ) do={:set bgplocalpref "bgp-local-pref=$bgplocalpref"}

/ip route add dst-address=$dstaddress gateway=$gateway $bgplocalpref

However this also simply generates an error (I’d expected that it’d just continue on with the ‘add’ command if there was no value assigned to the variable.

Out of ideas now.. anyone else run into this before?

Do an if block that checks if the variable is set, and if not set it explicitly to “” - an empty string. Then assign blindly.

Tried that a bit more in depth and I think I might have figured it out.
Passing a blank value to the command for SOME variables via a script gives an error, while doing it via terminal seems to work fine.

Try this script on your own router:

:local bgplocalpref ""
/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-local-pref=$bgplocalpref

Whereas running:

/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-local-pref=

from terminal works fine.

It would seem that it’s only specific values it occurs to, as the following would indicate:

:local a ""
:local b ""

/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-communities=$a
/ip route add dst-address=192.168.1.0/24 gateway=192.168.0.254 bgp-local-pref=$b

If you comment out the bgp-local-pref line it runs fine.

I’m going to ticket and see what I get back, thanks for the suggestion :slight_smile:

The following works as required:

#Set initial entry command
:set cmd "/ip route add"

#Import current entry (Some entries cannot be entered as blank, must check these beforehand)

:if ([:len $distance] > 0 ) do={:set cmd "$cmd distance=$distance"}
:if ([:len $dstaddress] > 0 ) do={:set cmd "$cmd dst-address=$dstaddress"}
:if ([:len $gateway] > 0 ) do={:set cmd "$cmd gateway=$gateway"}
:if ([:len $routingmark] > 0 ) do={:set cmd "$cmd routing-mark=$routingmark"}
:if ([:len $bgpaspath] > 0 ) do={:set cmd "$cmd bgp-as-path=$bgpaspath"}
:if ([:len $bgpatomicaggregate] > 0 ) do={:set cmd "$cmd bgp-atomic-aggregate=$bgpatomicaggregate"}
:if ([:len $bgpcommunities] > 0 ) do={:set cmd "$cmd bgp-communities=$bgpcommunities"}
:if ([:len $bgplocalpref] > 0 ) do={:set cmd "$cmd bgp-local-pref=$bgplocalpref"}
:if ([:len $bgpmed] > 0 ) do={:set cmd "$cmd bgp-med=$bgpmed"}
:if ([:len $bgporigin] > 0 ) do={:set cmd "$cmd bgp-origin=$bgporigin"}
:if ([:len $bgpprepend] > 0 ) do={:set cmd "$cmd bgp-prepend=$bgpprepend"}
:if ([:len $comment] > 0 ) do={:set cmd "$cmd comment=\"$comment\""}
:if ([:len $disabled] > 0 ) do={:set cmd "$cmd disabled=$disabled"}

:execute $cmd;

#End of selective add