Community discussions

MikroTik App
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

the irrationality of [find]

Wed Oct 02, 2024 9:52 am

Hello,
Today I noticed an inconsistency of [find] in the script:
When I try to reset counter of "a" user in hotspot, I use:
/ip hotspot user reset-counters [find name="a"];
Everything was perfect until I removed "a".
According to common thinking, my command line above will look for "a" to reset the counter, if it can't find "a", it won't do anything. But surprisingly, when it can't find "a", it reseted all other users as if to vent its anger. It's so hard for other users, just because a doesn't exist, they are affected by a command that has nothing to do with them. Is this a ROS7 bug?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4089
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: the irrationality of [find]

Wed Oct 02, 2024 9:55 am

No. [find] mean "all". It's a filter, so if you don't apply any filters like name="a" to match, the default is return all. Otherwise, the would be no way to express "find everything".

You can test find by using it standalone:
:put [/ip hotspot user find name=a]
*29
:put [/ip hotspot user find]
*0;*2;*3;...

And the numbers from "find" are the same as "/ip hotspot user print show-id" or "/ip hotspot user print show-id where name=a". So you can use the "where <filters>" clause to test, and the use that in a "/ip/hotspot/user reset-counters [find <filters>]". FWIW, in a print statement, "where" is same as "find" - but it named where since it a clause in the expression, not a standalone command requiring [].

It's powerful, but not easy at first.
 
msatter
Forum Guru
Forum Guru
Posts: 2936
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: the irrationality of [find]

Wed Oct 02, 2024 10:30 am

Amm0
Otherwise, the would be no way to express "find everything".
you can find all by using a Regex.
/user> :put [find name~"."] 
*1;*2;*4;*6;*9
/user> :put [find]         
*1;*2;*4;*6;*9
So there was no need to have find only "find" selection being that powerful. It is a shortcut as it is implemented now, it has it's pitfalls.

General information:
/user> :put [find name~"a"] 
*1;*2
/user> :put [find name="a"]

The line with ~ in it will find any names with an "a" in it and the the one with = in it, needs an exact match. The second line does so not find any names.
 
infabo
Forum Guru
Forum Guru
Posts: 1329
Joined: Thu Nov 12, 2020 12:07 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 10:39 am

What Wheelhousemarine really wanted to report is, translated to commands:
/ip hotspot user reset-counters [find name="a"];
/ip hotspot user remove a;
/ip hotspot user reset-counters [find name="a"]; -> resets counters of ->ALL<- users
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4089
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: the irrationality of [find]

Wed Oct 02, 2024 11:17 am

Now I get it. I ain't arguing this is great. But it's rational.

/ip/hotspot/user/reset-counters has some trickier logic... here "numbers=" attribute is optional. And numbers= is actual name of attribute used by the unnamed arg used by [find name=a]. So "reset-counter" already assumes all, if numbers= is not provided. And since numbers= cannot be set to an empty list, it's ignored.

Why it doesn't happen elsewhere... is normally when you a find in something like /ip/address/set [find comment="xxx"]... and the find results in 0 match... the "set" will FAIL, since it requires a some .id/numbers= to set.

Not saying this correct or ideal. But since "reset-counters" will work without any .id's (i.e. numbers= is optional), that why a "failed find" actually does NOT block it since numbers=/.ids are optional.
 
jaclaz
Forum Guru
Forum Guru
Posts: 1724
Joined: Tue Oct 03, 2023 4:21 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 11:30 am

So it is not a quirk of the find command in itsellf, but rather a "wrong implied default" of "all" in the command /ip hotspot user reset-counters?

How can it be worked around?
Like checking if "numbers" is defined and only run the command if the condition is true?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4089
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: the irrationality of [find]

Wed Oct 02, 2024 11:40 am

So it is not a quirk of the find command in itsellf, but rather a "wrong implied default" of "all" in the command /ip hotspot user reset-counters?
That's what I'm suggesting: it's the command's logic, not find's logic at issue. A zero-length list is NOT nil/[:nothing], so reset-counter should treat an empty list as just "nothing to reset", not ignore it because it's an empty list...
:put [:typeof [/ip hotspot user find name=a]]                      
# array
:put [:len [/ip hotspot user find name=a]]      
# 0
You can of course check the list with [:len] before calling reset-counter, and be okay for schedule script...but checking the list be a PITA at the CLI.

Welcome to file an issue and see with Mikrotik says. I cannot find the post, but I think this one has come up before...
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 4:00 pm

the one with = in it, needs an exact match. The second line does so not find any names.
yes, and do you know and why does the statement affect all users when the condition [find name=a] returns that no user satisfies. I think this is very error prone.
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 4:04 pm

No. [find] mean "all". It's a filter, so if you don't apply any filters like name="a" to match, the default is return all. Otherwise, the would be no way to express "find everything".

You can test find by using it standalone:
:put [/ip hotspot user find name=a]
*29
:put [/ip hotspot user find]
*0;*2;*3;...
[find] mean all, ok, no problem, but why [find name=a] still mean all if "a" removed?
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 4:08 pm

So it is not a quirk of the find command in itsellf, but rather a "wrong implied default" of "all" in the command /ip hotspot user reset-counters?

How can it be worked around?
Like checking if "numbers" is defined and only run the command if the condition is true?
yes, there are many ways to fix this "bug", I just brought up an irrationality of the [find] condition.
 
jaclaz
Forum Guru
Forum Guru
Posts: 1724
Joined: Tue Oct 03, 2023 4:21 pm

Re: the irrationality of [find]

Wed Oct 02, 2024 4:38 pm

yes, there are many ways to fix this "bug", I just brought up an irrationality of the [find] condition.
But that [find name="a"] works just fine, as it finds nothing and returns nothing.

The issue is in the command:
/ip hotspot user reset-counters
that works for "all" even if no parameters are passed to it.
 
User avatar
Larsa
Forum Guru
Forum Guru
Posts: 1531
Joined: Sat Aug 29, 2015 7:40 pm
Location: The North Pole, Santa's Workshop

Re: the irrationality of [find]

Thu Oct 03, 2024 4:13 am

Yeah, and as a workaround, you’ll need to use for example a foreach loop. Something like this:

/ip hotspot user
:foreach user in=[find name~"^adam"] do={
reset-counters $user
another-command $user
etc…
}
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

Re: the irrationality of [find]

Thu Oct 03, 2024 5:53 am

yes, there are many ways to fix this "bug", I just brought up an irrationality of the [find] condition.
But that [find name="a"] works just fine, as it finds nothing and returns nothing.
No, if it find nothing, it return all. surprise?
[/quote]

The issue is in the command:
/ip hotspot user reset-counters
that works for "all" even if no parameters are passed to it.
[/quote]
No, i am not user command /ip hotspot user reset-counters; i used: /ip hotport user reset-counters [find name = "a"]; but it still works for all in case "a" is removed.
 
jaclaz
Forum Guru
Forum Guru
Posts: 1724
Joined: Tue Oct 03, 2023 4:21 pm

Re: the irrationality of [find]

Thu Oct 03, 2024 11:37 am

No, i am not user command /ip hotspot user reset-counters; i used: /ip hotport user reset-counters [find name = "a"]; but it still works for all in case "a" is removed.
Exactly. :)

You use the command:
/ip hotspot user reset-counters [find name = "a"]
BUT the find command cannot find that particular user, and returns an empty value, so the command becomes:
/ip hotspot user reset-counters <nothing>
which is actually:
/ip hotspot user reset-counters

The problem is in the command, that shouldn't do anything if issued without any argument, and to delete all users there would be the need for a special parameter *like*:
/ip hotspot user reset-counters all
 
Wheelhousemarine
just joined
Topic Author
Posts: 10
Joined: Thu Sep 19, 2024 5:20 pm

Re: the irrationality of [find]

Thu Oct 03, 2024 4:17 pm

No, i am not user command /ip hotspot user reset-counters; i used: /ip hotport user reset-counters [find name = "a"]; but it still works for all in case "a" is removed.
Exactly. :)

You use the command:
/ip hotspot user reset-counters [find name = "a"]
BUT the find command cannot find that particular user, and returns an empty value, so the command becomes:
/ip hotspot user reset-counters <nothing>
which is actually:
/ip hotspot user reset-counters

The problem is in the command, that shouldn't do anything if issued without any argument, and to delete all users there would be the need for a special parameter *like*:
/ip hotspot user reset-counters all
thanks, i understand how it works.
just, i'm not comfortable with do-something-for<nothing> = do-something-for<all>
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4089
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: the irrationality of [find]

Thu Oct 03, 2024 5:54 pm

Oh you should file a bug report. The "reset-counters" should handle the case there is a find & it's nothing.

Just because it's explainable, does mean it makes sense. :?
 
User avatar
Larsa
Forum Guru
Forum Guru
Posts: 1531
Joined: Sat Aug 29, 2015 7:40 pm
Location: The North Pole, Santa's Workshop

Re: the irrationality of [find]

Thu Oct 03, 2024 6:33 pm

I totally agree. Everything should be handled consistently and users shouldn't have to know all the little exceptions that could lead to serious issues. At the very least, the documentation should have clear warnings about these risks.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4089
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: the irrationality of [find]

Thu Oct 03, 2024 9:38 pm

I totally agree. Everything should be handled consistently and users shouldn't have to know all the little exceptions that could lead to serious issues. At the very least, the documentation should have clear warnings about these risks.
Basically anything that appears on the right-side "Actions" in the new Winbox4 is going to be trickier in CLI...since these "special verbs" all deviate from standard list/items with get/set/find/print/enable/disable scheme in some ways. It's these verbs where the CLI dragons live.

I think Mikrotik does not always get reports about some of these, since folks move on to the next thing... is part of the problem. And, even if they did, might miss the issues. e.g. without @infabo's explanation above, it sounded more like a complaint about [:find]:
/ip hotspot user reset-counters [find name="a"];
/ip hotspot user remove a;
/ip hotspot user reset-counters [find name="a"]; -> resets counters of ->ALL<- users
 
msatter
Forum Guru
Forum Guru
Posts: 2936
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: the irrationality of [find]

Thu Oct 03, 2024 10:25 pm

Thinking differently and avoiding so unwanted results:

Preferred way to do this and I found this in an other topic viewtopic.php?t=211390:
:foreach r in=[find name="test"] do={reset-counters $r; :put "Counters zeroed"}

Older remarks:
:local username "test"; :if [find name=$username] do {reset-counters [find name=$username]; :put "Counters zeroed for user: $username"} else {:put "Warning: User $username not found!"}
And then, why are we using find, when the default search field is "name"?

User test exists:
/ip/hotspot/user> reset-counters test 
/ip/hotspot/user> reset-counters fa  
no such item
/ip/hotspot/user> :do {reset-counter fa; :put "counters zeroed."} on-error={:put "Not found"}
Not found
/ip/hotspot/user> :do {reset-counter test; :put "counters zeroed."} on-error={:put "Not found"}
counters zeroed.
Then RouterOS is correctly working when the selector is name. However if you want to use a different selector then you need to use find. Which does produce unwanted results when there is no match.

Who is online

Users browsing this forum: steamy and 17 guests