Ex:
:global VALUE true
:foreach varname in "VAR1\n\rVAR2\n\rVAR3" \
do={
:global "$varname" $VALUE
}
:global VALUE true
:foreach varname in "VAR1\n\rVAR2\n\rVAR3" \
do={
:global "$varname" $VALUE
}
:foreach varname in={"VAR1" ; "VAR2" ; "VAR3" } do={:parse ":global $varname \$VALUE" }
:foreach varname in={"VAR1" ; "VAR2" ; "VAR3" } do={:execute ":global $varname \$VALUE" }
I used $VALUE instead of \$VALUE, but it worked perfectly.Using ":execute" instead of ":parse", it works :
Code: Select all:foreach varname in={"VAR1" ; "VAR2" ; "VAR3" } do={:execute ":global $varname \$VALUE" }
Hi Tal,I used $VALUE instead of \$VALUE, but it worked perfectly.
It didn't seem to work for me when I used "\$VALUE", but I'll try again. Pretty useful bit of info - thanks.Hi Tal,I used $VALUE instead of \$VALUE, but it worked perfectly.
Without "\" it works for most values. But If VALUE contains, for example, a string with spaces or special characters, "$VALUE" won't work while "\$VALUE" will...
BTW, a warning: I may have missed something but AFAIK, if the ":execute" f command fails, you get no error message of any kind.
Fabrice
This code doesn't work. But it may give a hint toward a solution :
foreach varname in={"VAR1"; "VAR2"; "VAR3"} do={[parse "global $varname true"]}
Store the dynamically created local variables in an array.Works with global, but not possible with local. Is the any solution for local variables?
{
:local qty 9; # number of variables to create
:local varname "myvar"; # name for the variables
:local myarray [:toarray ""]; # create empty array
:for i from=1 to=$qty do={
:local tmp ($varname . [:tostr $i]); # dynamically construct name of the variable
:set ($myarray->$tmp) ""; # push the newly created variable into the array
}
# setting the variables
:set ($myarray->"myvar1") "plaintext"
:set ($myarray->"myvar2") {"abc"}
:set ($myarray->"myvar3")
:set ($myarray->"myvar4") true
:set ($myarray->"myvar5") 127.0.0.1
:set ($myarray->"myvar6") 23:59:59
:set ($myarray->"myvar7") 192.168.88.0/24
:set ($myarray->"myvar8") ::ffff:192.0.2.128
:set ($myarray->"myvar9") 2001:0DB8:0000:000b::/64
# reading the variables
:put ( "myvar1=" . ($myarray->"myvar1") . " type=" . [ :typeof ($myarray->"myvar1") ] )
:put ( "myvar2=" . ($myarray->"myvar2") . " type=" . [ :typeof ($myarray->"myvar2") ] )
:put ( "myvar3=" . ($myarray->"myvar3") . " type=" . [ :typeof ($myarray->"myvar3") ] )
:put ( "myvar4=" . ($myarray->"myvar4") . " type=" . [ :typeof ($myarray->"myvar4") ] )
:put ( "myvar5=" . ($myarray->"myvar5") . " type=" . [ :typeof ($myarray->"myvar5") ] )
:put ( "myvar6=" . ($myarray->"myvar6") . " type=" . [ :typeof ($myarray->"myvar6") ] )
:put ( "myvar7=" . ($myarray->"myvar7") . " type=" . [ :typeof ($myarray->"myvar7") ] )
:put ( "myvar8=" . ($myarray->"myvar8") . " type=" . [ :typeof ($myarray->"myvar8") ] )
:put ( "myvar9=" . ($myarray->"myvar9") . " type=" . [ :typeof ($myarray->"myvar9") ] )
}
yeah but this doesn't work in this setting, if you put space in the valuesYou just need square brackets:Code: Select allforeach varname in={"VAR1"; "VAR2"; "VAR3"} do={[parse "global $varname true"]}
foreach key,value in={"VAR1"="foo with space"; "VAR2"="bar"} do={[parse "global $key $value"]}
[admin@MikroTik] > :global vlancommon {id=100; name="VLAN_COMMON" ; comment="COMMON SERVICES AND DEVICES / OFFICE" }
[admin@MikroTik] > :put ($vlancommon)
comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON
[admin@MikroTik] > :put ($vlancommon->"name")
vlancommon
[admin@MikroTik] > :put ([ :toarray "UP, vlancommon ,KIDS" ]->1)
vlancommon
[admin@MikroTik] > :put (:parse "\$([ :toarray "UP, vlancommon ,KIDS" ]->1)"->"name")
comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON
VLAN_COMMON
Any idea what the last command has to look like to get the second element of the array vlancommon ?
:put ( ( :parse "\$([ :toarray "UP, vlancommon ,KIDS" ]->1)" ) -> "name")
Last but not least, how to modify when I going to use capital later and/or symbols in the variable name and/or array key name so that they have to be put in quotes?
:put ( ( :parse "\$\"([ :toarray "UP, vlancommon ,KIDS" ]->1)\"" )->"name")
:global variablename "test" # Create or set a value (on same command) [:parse ":global $variablename \"REX1\""] :put $test # Set a value (or simply apply previous command) [:parse "global $variablename;:set $variablename \"REX2\""] :put $test # For read the variable inside another declared variable: :global testx [:parse "global $variablename;:global testx \$$variablename"] :put $testx
I made an error here; did not test "vlan_common".and pair of \"Last but not least, how to modify when I going to use capital later and/or symbols in the variable name and/or array key name so that they have to be put in quotes?Code: Select all:put ( ( :parse "\$\"([ :toarray "UP, vlancommon ,KIDS" ]->1)\"" )->"name")
:put ( ( :parse "\$\"([ :toarray "UP, vlan_common ,KIDS" ]->1)\"" )->"name")
:put ">$([:toarray "UP, vlancommon ,KIDS"]->1)<"
>vlancommon <
:put ">$([:toarray "UP,vlancommon,KIDS"]->1)<"
>vlancommon<
try the same but replace vlancommon by vlan_commonfor example, start to remove all significant spaces:
Code: Select all:put ">$([:toarray "UP, vlancommon ,KIDS"]->1)<" >vlancommon < :put ">$([:toarray "UP,vlancommon,KIDS"]->1)<" >vlancommon<
VLAN_COMMON
[admin@MikroTik] > :global "vlan_common" {id=100; name="VLAN_COMMON" ; comment="COMMON SERVICES AND DEVICES / OFFICE" }
:global vlancommon {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"}
:put ($vlancommon)
:put ($vlancommon->"name")
:put ([:toarray "UP,vlancommon,KIDS"]->1)
:global testx
[:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"id\")"]
:put $testx
[:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"name\")"]
:put $testx
[:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"comment\")"]
:put $testx
[mikro@tik] > :global vlancommon {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"} [mikro@tik] > :put ($vlancommon) comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON [mikro@tik] > :put ($vlancommon->"name") VLAN_COMMON [mikro@tik] > :put ([:toarray "UP,vlancommon,KIDS"]->1) vlancommon [mikro@tik] > :global testx [mikro@tik] > [:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"id\")"] [mikro@tik] > :put $testx 100 [mikro@tik] > [:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"name\")"] [mikro@tik] > :put $testx VLAN_COMMON [mikro@tik] > [:parse "global vlancommon;:global testx (\$$([:toarray "UP,vlancommon,KIDS"]->1)->\"comment\")"] [mikro@tik] > :put $testx COMMON SERVICES AND DEVICES / OFFICE [mikro@tik] >
[mikro@tik] > :global vlancommon {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"}
[mikro@tik] > :global "vlan_common" {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"}
Warning: Key name in array contains any character other than lowercase character, it should be put in quotes
because I would like to know how to deal with:Why you mix the cards?
I talk about spaces on array elements, not underscores....
:global "vlan_common" {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"}
:put ($"vlan_common")
:put ($"vlan_common"->"name")
:put ([:toarray "UP,vlan_common,KIDS"]->1)
:global testx
[:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"id\")")]
:put $testx
[:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"name\")")]
:put $testx
[:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"comment\")")]
:put $testx
[mikro@tik] > :global "vlan_common" {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"} [mikro@tik] > :put ($"vlan_common") comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON [mikro@tik] > :put ($"vlan_common"->"name") VLAN_COMMON [mikro@tik] > :put ([:toarray "UP,vlan_common,KIDS"]->1) vlan_common [mikro@tik] > :global testx [mikro@tik] > [:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"id\")")] [mikro@tik] > :put $testx 100 [mikro@tik] > [:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"name\")")] [mikro@tik] > :put $testx VLAN_COMMON [mikro@tik] > [:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"comment\")")] [mikro@tik] > :put $testx COMMON SERVICES AND DEVICES / OFFICE [mikro@tik] >
[:parse ("global \"vlan_common\";:global testx (\$\"$([:toarray "UP,vlan_common,KIDS"]->1)\"->\"name\")")]
:global readfromthis ([:toarray "UP,vlan_common,KIDS"]->1)
:global readthisfield "name"
[:parse ("global \"vlan_common\";:global testx (\$\"$readfromthis\"->\"$readthisfield\")")]
but>>>in particular (\$\"$
>>>as I would expect that
>>>:put ( ( :parse ("\$\"vlan_common\" ") ) )
>>>gives the content of global "vlan_common"
again, ":put" can not read ":parse" as expected from you...
[admin@MikroTik] <SAFE> :put ( :parse ("$(vlancommon)") )
comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON
declaration is done in line one, so why doing it again?>>>great
>>>may you explain why
>>>[:parse ("global \"vlan_common\";:global testx (\$\"$([
>>>is necessary?
Because you must declare the variable used or do not work
when you write ":put (:parse ...)" on that way, simply the script convert vlancommon value (array) to "instructions" and the result is "comment...." (because internally the arrays are sort)but>>>in particular (\$\"$
>>>as I would expect that
>>>:put ( ( :parse ("\$\"vlan_common\" ") ) )
>>>gives the content of global "vlan_common"
again, ":put" can not read ":parse" as expected from you...worksCode: Select all[admin@MikroTik] <SAFE> :put ( :parse ("$(vlancommon)") ) comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON
will doplease do not give "but", only questions.
# name the device being configured
/system identity set name="AP+ES_GF_MT-hAP-ac3"
# create one bridge, with defaults only
/interface bridge
add name=bridge-VLANs
# add VLANs
/interface vlan
add interface=bridge-VLANs vlan-id=999 name=VLAN_MGMT comment="NETWORK DEVICES MANAGEMENT VLAN"
# VLAN interface for L3 Management Access
/ip address
add address=10.10.9.001/24 interface=VLAN_MGMT comment="NETWORK DEVICES MANAGEMENT VLAN" --> CR_2B_MT-CCR1009-8G-1S-1S+
add address=10.10.9.002/24 interface=VLAN_MGMT comment="NETWORK DEVICES MANAGEMENT VLAN" --> CS-PoE_2B_MT-CRS328-24P-4S+
# The route to the router to allow L3 communication.
/ip route
add gateway=10.10.9.1 distance=1
# DNS server, to allow ROS to resolve DNS queries from the CPUto fetch updates etc.
/ip dns
set allow-remote-requests=no servers="10.10.9.1"
#ES_GF-E_MT-hEX-S
/interface ethernet
set comment="TP, VLAN-TRUNK TO CORE-SWITCH-SFP" [find name=sfp1]
set comment="UP, don't touch (temporarily)" [find name=ether1]
set comment="UP, VLAN_USER1, OFFICE, UNMANAGED SWITCH" [find name=ether2]
set comment="UP, VLAN_USER2, KIDS" [find name=ether3]
set comment="UP, VLAN_USER2, LIVING ROOM" [find name=ether4]
set comment="UP, don't touch (temporarily)" [find name=ether5]
## START OF SCRIPT
#creating variable per VLAN and other variables
:global "VLAN_BKHOLE" { vlanid=001; name="VLAN_BKHOLE" ; comment="BLACKHOLE" }
:global "VLAN_SYS" { vlanid=008; name="VLAN_SYS" ; comment="SYS" }
:global "VLAN_GUEST" { vlanid=011; name="VLAN_GUEST" ; comment="GUEST" }
:global "VLAN_USER1" { vlanid=110; name="VLAN_USER1" ; comment="USER 1,all devices in one vlan" }
:global "VLAN_USER2" { vlanid=120; name="VLAN_USER2" ; comment="USER 2,all devices in one vlan" }
:global filterUP "^UP, VLAN_USER"
:global BridgeName "bridge-VLANs"
:global result
#show configuration before script execution
interface ethernet print where comment~"^UP."
interface bridge port print
#clear anything in /interface bridge port if there is an existing configuration
:put "CLEAR EXISTING BRIDGE PORT CONFIGURATION
:foreach Interface in=[ /interface bridge port find ] do={ /
/interface bridge port remove $Interface
}
#show that /interface bridge port is empty
/interface bridge port print
#add Bridge Ports according to the comment of the interfaces. PVID is set as well.
:put "STARTING SCRIPT-BASED BRIDGE PORT CREATION
:foreach Interface in=[ /interface ethernet find where comment~$filterUP ] do={ /
:local readcomment ( [ :toarray ([/interface ethernet get $Interface]->"comment" ) ]->1 )
:local readthisfield "vlanid"
[:parse ("global \"$readcomment\";:global result (\$\"$readcomment\"->\"$readthisfield\")")]
/interface bridge port add interface=$Interface bridge=$BridgeName pvid=$result
}
"show result
:put "SHOW RESULTS"
/interface ethernet print where comment~"^UP,"
/interface bridge port print
/interface bridge port print where pvid=110
/interface bridge port print where pvid=120
/interface ethernet print where comment~"^UP,"
Flags: R - RUNNING; S - SLAVE
Columns: NAME, MTU, MAC-ADDRESS, ARP, SWITCH
# NAME MTU MAC-ADDRESS ARP SWITCH
;;; UP, don't touch (temporarily)
0 R ether1 1500 08:55:31:0F:52:97 enabled switch1
;;; UP, VLAN_USER1, OFFICE, UNMANAGED SWITCH
1 S ether2 1500 08:55:31:0F:52:98 enabled switch1
;;; UP, VLAN_USER2, KIDS
2 S ether3 1500 08:55:31:0F:52:99 enabled switch1
;;; UP, VLAN_USER2, LIVING ROOM
3 S ether4 1500 08:55:31:0F:52:9A enabled switch1
;;; UP, don't touch (temporarily)
4 ether5 1500 08:55:31:0F:52:9B enabled switch1
CLEAR EXISTING BRIDGE PORT CONFIGURATION
STARTING SCRIPT-BASED BRIDGE PORT CREATION
SHOW RESULTS
/interface ethernet print where comment~"^UP,"
Flags: I - INACTIVE; H - HW-OFFLOAD
Columns: INTERFACE, BRIDGE, HW, PVID, PRIORITY, PATH-COST, INTERNAL-PATH-COST, HORIZON
# INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON
0 IH ether2 bridge-VLANs yes 110 0x80 10 10 none
1 IH ether3 bridge-VLANs yes 120 0x80 10 10 none
2 IH ether4 bridge-VLANs yes 120 0x80 10 10 none
[admin@MikroTik] /interface/mesh> /interface bridge port print where pvid=110
Flags: I - INACTIVE; H - HW-OFFLOAD
Columns: INTERFACE, BRIDGE, HW, PVID, PRIORITY, PATH-COST, INTERNAL-PATH-COST, HORIZON
# INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON
0 IH ether2 bridge-VLANs yes 110 0x80 10 10 none
[admin@MikroTik] /interface/mesh> /interface bridge port print where pvid=120
Flags: I - INACTIVE; H - HW-OFFLOAD
Columns: INTERFACE, BRIDGE, HW, PVID, PRIORITY, PATH-COST, INTERNAL-PATH-COST, HORIZON
# INTERFACE BRIDGE HW PVID PRIORITY PATH-COST INTERNAL-PATH-COST HORIZON
1 IH ether3 bridge-VLANs yes 120 0x80 10 10 none
2 IH ether4 bridge-VLANs yes 120 0x80 10 10 none
:global result
:local readcomment ( [ :toarray ([/interface ethernet get $Interface]->"comment" ) ]->1 )
:local readthisfield "vlanid"
:global result
:local readcomment ( [ :toarray ([/interface ethernet get $Interface]->"comment" ) ]->1 )
:local readthisfield "vlanid"
:local result
[:parse ("global \"$readcomment\";:global result (\$\"$readcomment\"->\"$readthisfield\")")]
[:parse ("lcoal \"$readcomment\";:global result (\$\"$readcomment\"->\"$readthisfield\")")]
invalid value for pvid, an integer required
I think I almost have it, see below.I understand you want know how the scripts works,...
[admin@MikroTik] > :global "vlan_common" {id=100;name="VLAN_COMMON";comment="COMMON SERVICES AND DEVICES / OFFICE"}
[admin@MikroTik] > :put ($"vlan_common")
comment=COMMON SERVICES AND DEVICES / OFFICE;id=100;name=VLAN_COMMON
[admin@MikroTik] > put [:parse ("global \"vlan_common\" ") ]
(evl /globalname=$vlan_common)
[rex@net] > :put [:parse ":put 777"]
(eval /putmessage=777)
[rex@net] > [:parse ":put 777"]
777
:local id 1;
:local nwshost Tes1,Tes2,Tes3,Tes4,Tes5,Tes6,Tes7,Tes8,Tes9
:foreach nwsarr in=$nwshost do={
:local date [/system clock get date]
:local time [/system clock get time]
[:parse ":global Down$nwsarr"];
[:parse ":global check$nwsarr"];
[
:execute (" \
:if (\$\"check$nwsarr\" != 1) do={ :set check$nwsarr \"2\"; }; \; \
:set Down$nwsarr \"$date $time\"; \
")
];
:set id ($id+1)
}
/system clock :local datetime "$[get date] $[get time]" :local nwshost ("Tes1","Tes2","Tes3","Tes4","Tes5","Tes6","Tes7","Tes8","Tes9") :local id (1 + [:len $nwshost]) :foreach item in=$nwshost do={ [:parse ":global check$item ; :if (\$check$item != 1) do={:set check$item 2}"] [:parse ":global Down$item \"$datetime\""] }
If in executeJust necroposting. Nothing usable and full of frills and errors. For example: :if (check$nwsarr must be :if (\$check$nwsarr
similar functionality code
/system clock :local datetime "$[get date] $[get time]" :local nwshost ("Tes1","Tes2","Tes3","Tes4","Tes5","Tes6","Tes7","Tes8","Tes9") :local id (1 + [:len $nwshost]) :foreach item in=$nwshost do={ [:parse ":global check$item ; :if (\$check$item != 1) do={:set check$item 2}"] [:parse ":global Down$item \"$datetime\""] }
{ :global gev :if ([:typeof [$gev]] = "nil") do={:global gev [:toarray ""]} /system clock :local datetime "$[get date] $[get time]" :local nwshost ("Tes1","Tes2","Tes3","Tes4","Tes5","Tes6","Tes7","Tes8","Tes9") :local id (1 + [:len $nwshost]) # added for test :set ($gev->"checkTes2") 1 ; # for test if work (($gev->"checkTes2") != 1) :foreach item in=$nwshost do={ :if (($gev->"check$item") != 1) do={:set ($gev->"check$item") 2} :set ($gev->"Down$item") $datetime } # added for test :put ($gev->"checkTes2") :put ($gev->"DownTes2") :put ($gev->"checkTes4") :put ($gev->"DownTes4") }