Because where property of print command expects textual argument but [ find where …] provides list of interfaces in format alien to where … and print simply ignores it (try running “/interface/print where” ).
Almost correct, except that there are two kinds of IDs - the internal one that stays the same as long as the object exists and is shown as *1fe or something alike (a 32-bit number in hexadecimal representation prefixed with an asterisk). These are the IDs that [find …] returns. As @mkx has already said, it actually always returns a list, try the following: :put [/interface/ethernet/find where name~“ether”]
:put [:typeof [/interface/ethernet/find where name~“ether”]]
But even if you restrict the condition to just a single item, find … still returns a list, except that put (and many other operations) performs an automatic conversion from a single-item list (array) to a scalar: :put [/interface/ethernet/find where name~“ether1”]
:put ([/interface/ethernet/find where name~“ether1”]->0)
:put [:typeof [/interface/ethernet/find where name~“ether1”]]
Each print assigns user-friendly aliases to the internal IDs, in the form of numbers in decimal representation; these aliases are only valid in the shell where they have been assigned and only until the next print of the same configuration branch. Try the following: /ip/firewall/mangle/add chain=test917 dst-address=1.1.1.1 action=passthrough
/ip/firewall/mangle/add chain=test917 dst-address=2.2.2.2 action=passthrough
/ip/firewall/mangle/add chain=test917 dst-address=3.3.3.3 action=passthrough
A jump to chain test917 is (hopefully) not used anywhere in mangle, so these rules are never actually used.
Now do /ip/firewall/mangle/print where chain=test917
it shows you those items numbered 0, 1, and 2. /ip/firewall/mangle remove 0 will remove the first one (with dst-address=1.1.1.1), but another /ip/firewall/mangle/print where chain=test917 will assign the “user-friendly ID” 0 to the first remaining one (with dst-address=2.2.2.2).
I would add that issuing “enough”:
/ip/firewall/mangle remove 0
until you get an error like “no such item” you effectively make the the mangle list empty.
If you issue a command that refers to the user-friendly ID before you use the first print for that configuration branch, RouterOS silently assigns the user-friendly IDs the same way it would if you issued a print for that branch without specifying any conditions. But once generated, the user-friendly IDs stick to the internal ones, so if you remove the 0 once and try again without using (another) print first, you get no such item (4).
The older I get the more I bump into the situation, that I believe is axiomatic, whereby everything is far far more complicated than one knows at the moment.
[admin@729hAPax3] > :put [/interface/ethernet/find where name~"ether"]
*2;*3;*4;*5;*6
[admin@729hAPax3] > :put [:typeof [/interface/ethernet/find where name~"ether"]]
array
So *2 is the “internal id,” represented as ‘asterisk followed by 32 bit number’
And the "find where name~“ether” function is always of type: array
But even if you restrict the condition to just a single item, > find … > still returns a list, except that > put > (and many other operations) performs an automatic conversion from a single-item list (array) to a scalar: :put [/interface/ethernet/find where name~“ether1”]
:put ([/interface/ethernet/find where name~“ether1”]->0)
:put [:typeof [/interface/ethernet/find where name~“ether1”]]
And:
[admin@729hAPax3] > :put [/interface/ethernet/find where name~"ether1"]
*2
This shows the Internal ID of ether1 is *2
[admin@729hAPax3] > :put ([/interface/ethernet/find where name~"ether1"]->0)
*2
I don’t understand what the addition of “->0” does.
[admin@729hAPax3] > :put [:typeof [/interface/ethernet/find where name~"ether1"]]
array
This shows the type is still array, despite the result being a single value.
Each > print > assigns user-friendly aliases to the internal IDs, in the form of numbers in decimal representation; these aliases are only valid in the shell where they have been assigned and only until the next > print > of the same configuration branch. Try the following: /ip/firewall/mangle/add chain=test917 dst-address=1.1.1.1 action=passthrough
/ip/firewall/mangle/add chain=test917 dst-address=2.2.2.2 action=passthrough
/ip/firewall/mangle/add chain=test917 dst-address=3.3.3.3 action=passthrough
A jump to chain > test917 > is (hopefully) not used anywhere in > mangle> , so these rules are never actually used.
Now do /ip/firewall/mangle/print where chain=test917
it shows you those items numbered 0, 1, and 2.
Results:
[admin@729hAPax3] > ip/firewall/mangle/print where chain=test917
Flags: X - disabled, I - invalid; D - dynamic
0 chain=test917 action=passthrough dst-address=1.1.1.1
1 chain=test917 action=passthrough dst-address=2.2.2.2
2 chain=test917 action=passthrough dst-address=3.3.3.3
This shows the user-friendly version of the Internal ID. I assume it takes the form of a base-10 whole number?
/ip/firewall/mangle remove 0 > will remove the first one (with > dst-address=1.1.1.1> ), but another > /ip/firewall/mangle/print where chain=test917 > will assign the “user-friendly ID” 0 to the first remaining one (with > dst-address=2.2.2.2> ).
I certainly could be doing something wrong, but I don’t think it is working like that for me.
[admin@729hAPax3] > /ip/firewall/mangle remove 0
[admin@729hAPax3] > /ip/firewall/mangle remove 0
no such item (4)
[admin@729hAPax3] > ip/firewall/mangle/print where chain=test917
Flags: X - disabled, I - invalid; D - dynamic
1 chain=test917 action=passthrough dst-address=2.2.2.2
2 chain=test917 action=passthrough dst-address=3.3.3.3
[admin@729hAPax3] > /ip/firewall/mangle remove 0
no such item (4)
[admin@729hAPax3] >
[admin@729hAPax3] > ip/firewall/mangle/print where chain=test917
Flags: X - disabled, I - invalid; D - dynamic
1 chain=test917 action=passthrough dst-address=2.2.2.2
2 chain=test917 action=passthrough dst-address=3.3.3.3
Issuing: “/ip/firewall/mangle remove 0” appears to remove the 1.1.1.1 rule.
Issuing: “/ip/firewall/mangle remove 0” again results in “no such item” (as expected).
Issuing: “/ip/firewall/mangle/print where chain=test917” shows friendly IDs as “1” and “2”
Issuing: “/ip/firewall/mangle remove 0” results in “no such item”
Issuing: “/ip/firewall/mangle/print where chain=test917” confirming that the the only remaining rules has IDs of “1” and 2"
A list is implicitly also an array indexed by integers starting from 0. So ($thisList->0) is a reference to the first (“zeroth”) element of thisList. To make it even crazier, you can mix different types of indice in the same array, more to find in the scripting documentation.
It’s not you, it’s the developers who keep “making it even better”. I have specially tested it on ROS 7.16.2 before posting and it worked the same like in ROS 6, i.e. the user-friendly IDs were assigned from scratch with each print. I have double-checked just now: [me@myTik] > ip firewall/mangle/add action=passthrough chain=test
[me@myTik] > ip firewall/mangle/add action=passthrough chain=test
[me@myTik] > ip firewall/mangle/print chain=test
Flags: X - disabled, I - invalid; D - dynamic
0 chain=test action=passthrough
1 chain=test action=passthrough
[me@myTik] > ip firewall/mangle/remove 0
[me@myTik] > ip firewall/mangle/print chain=test
Flags: X - disabled, I - invalid; D - dynamic
0 chain=test action=passthrough
So the bottom line is never the user-friendly IDs without using print right before.
@all
do not mix IDs and (print) line number.
if you write remove X is readed as remove number=X
If X is one ID, is directly removed,
If X is one number, is internally converted in one ID first, based on latest “print”
false
I’ll start by saying that what you wrote in the OP doesn’t make sense, and it doesn’t work that way.
/interface print where [find name=ether2]
is equal to write
/interface print where ([:tobool [/interface find where name="ether2"]] = true)
“where” accept true and false, and RouterOS try to convert the result of “find” that is one array that contain the ether2 id to one boolean value,
and is true because is not 0, empty, nothing or nil
so the final result (because ether2 exist) is:
/interface print where (true = true)
For the same reason, if you use unexistant interface, you got nothing:
/interface print where [find name=ether666]
The correct way to write something relevant is:
/interface print where name="ether2"
And I conclude with these bizarre, but valid ways, just for fun:
/interface print where .id=[find where name="ether2"]
/interface print where name=[get [find where name="ether2"] name]
My statement was based on the last part of last sentence:
Did you try it? When I tried it, it printed out all interfaces ... so how do you put it in your extensive explanation about boolean arithmetics (other than "NULL is true" logic)?