/port using the used-by property

Greetings to all !

It doesn’t seem like a difficult task at all, but I can’t cope:

:put [/port find name=usb2]

*1

:put [/port find name=usb2 !inactive]

*1

:put [/port find name=usb2 !inactive !used-by]

… nothing

:put [/port find name=usb2 !inactive used-by]

… nothing too !


:put [/port find !used-by]

… nothing !

:put [:typeof [/port find used-by]]

array

What’s the matter ? The “used-by” property is not read into the console? Something wrong with ROS or am I doing something wrong?
Tried it on ROS 6.46 - 6.48…

Although you can get the contents of the “used-by” property to the Terminal, for example:

/port print as-value

output:

.id=*1;baud-rate=auto;channels=1;device=;name=serial0;used-by=;.id=*2;baud-rate=9600;channels=7;device=1
-1;name=usb2;used-by=sms tool, PPP

[/foreach count in=[/port print as-value] do={:put ($count->("used-by"))}]

output:

Serial Console
sms tool, PPP

I will formulate the task once again (maybe I did not explain it clearly): How do I, when searching in :foreach, or just conditionally select only those ports from / port that are not used by anyone (free)?
Or can’t this be done for the used-by property? There must be a solution…

After all, router ports cannot have the same names (ROS does not make them the same itself and does not allow the user to set the same names to ports)

/port
:foreach item in=[find] do={
    :put [get $item "used-by"]
}

First, use right syntax
Second, the “find” results are ids, not field value.

I do not have usb2, only serial0:
:put [/port find where name=serial0]
*1
ok, *1 is the id of the serial0

:put [/port find name=serial0 !inactive !used-by]
(<- nothing here…)
nothing as expected, the serial0 is used by “Serial Console” (and is active)

:put [:typeof [/port find name=serial0 !inactive !used-by]]
array
as expected, is one empty array (of IDs)

after the previous examples I disable console on serial0 and…

:put [/port find name=serial0 used-by]
(<- nothing here…)
nothing (empty array) as expected, because !used-by is “when used-by not exist” and this probably never happen since used-by is always valorized…
not-used-by-something is used-by=“”
used-by-something is used-by!=“”
What you really want is

/port print where used-by=""
:put [/port find where used-by=""]

Rex, I’m so glad to talk to you!

It just happened that way:

:put [/port find used-by~""]]

Now I will write what the actual matter is …

You need to go through all the ports available on the router and select all of them that have the usb or serial type and only those that are active (!inactive) and only those that are not used by any devices (!used-by)…

I do this: (moment, please …)

Of course, I understand that the port can be occupied and freed, for example, by the console… My usb port is currently occupied by the modem, and serial0 is disconnected from the console, but …

:put [/port find name~"" !inactive !used-by]

output:

I don 't understand why… Maybe the OS router does not release the console port without rebooting? It doesn’t seem to be the case, because in /port print the ports are displayed correctly (usb is busy, serial0 is free from the console …)

I tried it on different versions, the effect is the same on different platforms with different number of ports and their occupancy…

You still not read what I write.

Retry.

On v7.14rc I get a syntax error with
:put [/port/find !inactive]

syntax error (line 1 column 12)

But using =no work instead of the !..
:put [/port find inactive=no]

*1;*2

And “used-by” is a string, and apparently empty if not used.
:put [/port/find inactive=no used-by=“”]

*2

This box has two serial, and one is serial is used:

0 name=“serial0” used-by=“remote-access” device=“” channels=1 baud-rate=115200
data-bits=8 parity=none stop-bits=1 flow-control=none
1 name=“serial1” used-by=“” device=“” channels=1 baud-rate=115200 data-bits=8
parity=none stop-bits=1 flow-control=none

Rex, I always read what you write! I try to read carefully, but I don’t always understand because of my poor English and the quality of the auto-translation into Russian (I already talked about this earlier). Please make allowances for my profession too (you know it) and the way patients pull me at work… Microtik is my hobby and I have to do it in very short periods of time… Everything suffers from this …

Please understand and don 't be offended …

The Router OS parser does not skip the construction:

:put [/port find name~"" inactive=no used-by=no]

apparently, the inactive parameter is readable and writable, and used-by exists only for reading (based on the Mikrotik Wiki /port)

used-by=no
  • can’t write (“no” it is not highlighted in green in the terminal !)

How can you achieve what you want in one line?

:put [/port find used-by=[]]
:put [/port find used-by=""]

*1

:put [/port find name~"^" used-by=""]]

*1

:put [/port find name~"^"]]

12 !!! (That is, without selection by used-by, the construction finds two identifiers - that is, I have two ports!)

:put [/port find name~"^" and !used-by~"^"]

:frowning:

 :put [/port find used-by~[:nothing]]

:frowning:

As a result, I “turned over” the Amm0 design and it worked like that!

:put [/port find used-by="" !inactive]

Or just like that:

:put [/port find inactive=no used-by=""]

The ROS is still the casket with the egg of kashchei the immortal !

Thank you very much, dear friends of Rex & Amm0! If you’ll excuse me, I (who in the scripts is up to both of you like the moon) That’s what they call you.

(don’t worry, I’m only offended by those who plot behind my back, cowards and traitors…)


As already written…

I came to the realization that I don’t understand the expression "

where

" at all… Not really knowing what it does, I’ve always tried not to use it in my scripts. The Mikrotik Wiki only says this:

where - expressions followed by where parameter can be used to filter out matched entries

But I still don’t understand how it really works in /find… I’m sorry, master…

What is the difference between /find and /find where ?

/port
:foreach item in=[find where name~"usb" and used-by="" and !inactive ] do={
    :put [get $item name]
}

This is correct ?

{:foreach item in=[/port find where name~"usb" and used-by="" and !inactive ] do={:put [/port get $item name]}}

output:

{:foreach item in=[/port find name~"usb" and !inactive ] do={:put [/port get $item name]}}

output:

usb2

Port usb2 is free …

Is it really impossible to run this search filter in one line of the script?

I can’t have any usb port to test, only serials, but the syntax is this:

/port
:foreach item in=[find where name~"usb" and used-by="" and inactive=no] do={:put [get $item name]}

Yes, OK. I checked it works correctly, including a shortened design:

{
/port
:foreach item in=[find where name~"usb" used-by="" !inactive] do={:put [get $item name]}
}

output:
usb2

But it also works without where…


{
/port
:foreach item in=[find name~"usb" used-by="" !inactive] do={:put [get $item name]}
}

output:
usb2

Rex, thank you. Please explain for me (so that I understand for the future)- why do you still need where? What does it do, if it works correctly without it?
Is the where parameter somehow involved in filtering, or can it actually be omitted?

With where and the "and"s:

Rex, thank you. Please explain for me (so that I understand for the future)- why do you still need where?

Without where and the "and"s:

Rx tk u pl. exp. 4 me so that I u-stand 4 future why u still need where?