Community discussions

MikroTik App
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

New command in RouterOs 7

Thu Aug 31, 2023 3:30 pm

As you know, the developers of Mikrotik finally took up the "scripts" section and supplemented the system with a number of new commands, such as, for example, : timestamp, : rndnum. Recent versions have received :convert, :jobname, tosec, /terminal/ask. But I did not find data on these commands in the official manual. Please tell me where I can read about them.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Thu Aug 31, 2023 3:33 pm

"<TAB>" is your friend, and some deduction...
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Thu Aug 31, 2023 3:35 pm

The only way ?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Thu Aug 31, 2023 3:38 pm

By now you should know how MikroTik staff works...
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Thu Aug 31, 2023 8:17 pm

I can’t understand how the :convert command works, what features and parameters it has ?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 8:31 pm

It's still in beta, so they don't doc it. In fact it change from one beta to the next. And...If stuff isn't obvious from <TAB>, that's good feedback on a beta. Since <tab> after the equal "=" char in transform=, from=, to= — you can see the choices.

The transform= make a lot of sense. The only tricky thing is to=/from= being "raw" generally means "string". Some examples are the release thread:
viewtopic.php?t=198723#p1021290 and viewtopic.php?t=198723#p1021098 ... e.g.


:convert transform=
ed25519-private-to-ed25519-public
reverse
ed25519-private-to-x25519-private
rot13
ed25519-public-to-x25519-public
sha512
md5
x25519-private-to-x25519-public
none

:convert to=
base32 base64 hex raw url

:convert from=
base32 base64 hex raw url

Now IMO, they should hold a release to "stable" if the docs for things aren't done – that's another topic – but in beta no docs makes sense.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Thu Aug 31, 2023 8:50 pm

Forgive me for being stupid, but could you explain why the :convert command is needed at all? The transform parameters are reminiscent of encryption options...
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 9:41 pm

Yeah the specific transform= options offered are lacking – like there is no "trim" to remove whitespace, nor transform="sha256", likely others.

But I think the scheme they're using is right. The transform= applies in-between any to= or from= – but transform=none is valid and the default. So you may not need a transform= in a lot of case. The default to= and from= is "raw", which a RouterOS string. Since RouterOS "string" can contain raw bytes like "\01\02\AA\AA", it's called "raw" – but still a :typeof == string.

Like base64 comes up in MIME encoding, so that work without a transform= since just encoding is needed:
:put [:convert "abcd" to=base64]                  
# YWJjZA==
:put [:convert from=base64 "YWJjZA==" ]                  
# abcd
But can be combine however you'd like...
:put [:convert from=base64 "YWJjZA==" transform=reverse]
# dcba
:put [:convert from=base64 "YWJjZA==" transform=reverse to=hex] 
# 64636261
and 64 is ASCII code for "d" in hex/base16, 63 = "c", etc.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Thu Aug 31, 2023 10:12 pm

Yeah interesting. It will probably solve many problems with various recodings and shorten scripts. Thanks a lot for the explanations.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 10:25 pm

Yeah interesting. It will probably solve many problems with various recodings and shorten scripts. Thanks a lot for the explanations.
Yeah, long way to covering all of @rextended's transformer scripts. ;) But being built-in would be better.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 10:34 pm

And, [:jobname] ... <TAB> isn't helpful there...

That stumped me at first. The CLI terminal itself apparently doesn't have a "jobname", so looked like it does nothing.
:put "jobname typeof: $[:typeof [:jobname]] len: $[:len [:jobname]]"
# jobname typeof: str len: 0

But <F1> shows at /:
:jobname -- return current script name

So a /system/script can use :jobname to get the script's name:
/system script add name=log-jobname source=\
    "/log info \"\$[:jobname]\""
and when run, "log-jobname" shows up in /log/print
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Thu Aug 31, 2023 10:38 pm

Oh..... finally.............................................................
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 11:17 pm

While one might assume the "n" in [:tonsec] means number – since it converts a time type to a num type.

But it really a "tonanosecs"...
:put [:tonsec 1s]  
1000000000
:put [:typeof [:tonsec 1s]]  
num
:put [:tonsec [:timestamp]]             
1693512717100098007
To get # of seconds from a time type....
:put ([:tonsec 1s]/1000000000)
# 1
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Thu Aug 31, 2023 11:23 pm

For completeness, /terminal/ask replaces using a [:return] or loop on [/terminal/inkey], to collect a string from the commands line
:global userinput [/terminal/ask preinput="preinput>" prompt="Some text that in prompt=" ]    
# Some text that in prompt=
# preinput>test
:put $userinput
# test
preinput= and prompt= seem backwards, but that's how it works... preinput is what appear just before the user input cursor & prompt is what shows above it.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Fri Sep 01, 2023 9:32 am

Thank you very much. Let's put in this topic everything that concerns the new Ros teams. It will be easy to search.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Fri Sep 01, 2023 1:51 pm

Is it possible to encode some data with a key using :convert, and then decode it only if this key is known?
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Fri Sep 01, 2023 2:35 pm

By the way, some descriptions of the new commands are present here:
https://help.mikrotik.com/docs/display/ROS/Scripting
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Fri Sep 01, 2023 4:13 pm

Is it possible to encode some data with a key using :convert, and then decode it only if this key is known?
I guess rot13 is not good enough "encryption" ;)...

But not at present. The transform='s in :convert are are either string operations or one-way hashes. The "ed25519-" are to deal with converting/extracting keys for EC-based SSH, but not the encryption.


[...] Let's put in this topic everything that concerns the new Ros teams. It will be easy to search.
Kinda my thought. Although, might want to change the title to include the 7.12 version in your title. e.g. "New commands in v7.12"
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Fri Sep 01, 2023 4:14 pm

There was also this in the v7.12 release notes, I'm not sure what was improved... Maybe someone else know this one?
*) console - improved multi-argument property parsing into array;
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Fri Sep 01, 2023 8:57 pm

No, I think it's better to post here for now all the new commands of the entire Router OS 7.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Fri Sep 01, 2023 11:31 pm

Well, that's easy. In terms of script-specific commands (e.g. not tied to a protocol/service), the only new ones (which are doc'd in link above already)

[:timestamp] - related to the :tonsec (and shown above), returns a "time" type contain the elapsed time from epoch (Jan 1, 1970), internally time is stored in nanoseconds.

[:rndnum from=0 to=1] - returns random "num" type (integer) using to= and from=

[:rndstr length=1] - returns a random "str" of length=

There is also...

/console/inspect - this is an "easter egg" – but I have an partial example of usage here:
viewtopic.php?t=175564&hilit=%2Fconsole ... ct#p966543

/task, which is like UNIX "bg", "fg", and "jobs" but I haven't used it.

[:retry] is also new I believe.
:retry delay=1s max=3 on-error={:put "got an error"} command={:put [/system/identity/get name]}
# Mikrotik
:retry delay=1s max=3 on-error={:put "I give up!"} command={:put "trying..."; :error "cause error"}                                
# trying...
# trying...
# trying...
# I give up!

Not directly scripting-specific, but "as-value" is new option in V7 for "/tool/snmp-get", which can get values from SNMP OID into a script without parsing required in V6:
{
   :local interfaceOneName [/tool/snmp-get oid=.1.3.6.1.2.1.2.2.1.2.1 address=127.0.0.1 community=public as-value] 
   :put $interfaceOneName
   :put ($interfaceOneName->"value")
}
# oid=1.3.6.1.2.1.2.2.1.2.1;type=octet-string;value=ether1
# ether1
note: requires /ip/snmp being enabled, and likely using different community name for better security

Similarly [:execute] now has "as-string" as option, which make it synchronous (e.g. waits for script to finished BEFORE return with new "as-string")
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Mon Sep 04, 2023 9:20 am

So, what we have today (to version 7.12):

:timestamp
:rndnum from=[num] to=[num]
:retry command={abc} delay=1 max=2 on-error={}
:rndstr from=[str] length=[num]
:convert from=[arg] to=[arg] transform=
:jobname
:tonsec
:terminal/ask preinput= prompt=
:console/inspect as-value request= path=
:task

:execute ..... as-string
*) console - improved multi-argument property parsing into array;
/tool /snmp-get ... as-value

The new RB has a lot of RAM now, and Microtik developers have actively begun to develop new features, including in scripts. The main thing is not to overdo it and document the developments. Surely there are hidden commands and command parameters. I wonder how Amm0 and Rextended learn new things in Roc7? Maybe someone uses reverse engineering? Or through :console/inspect ?
Last edited by Sertik on Mon Sep 04, 2023 11:25 am, edited 5 times in total.
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Mon Sep 04, 2023 9:30 am

I'll digress a little from the main topic of the topic and give examples of the possibility of entering a line in the Terminal:

To enter a line from the Terminal, of course, you can write a small script using :terminal inkey like this:
:local EnterString do={
     :local cont; :local string
        :while ($cont!=13) do={
          :if ([:len $string]<254) do={
             :local key ([:terminal inkey])
                :if ($key!=13) do={
                     :local char [[:parse "(\"\\$[:pick "0123456789ABCDEF" (($key >> 4) & 0xF)]$[:pick "0123456789ABCDEF" ($key & 0xF)]\")"]]
             :set string ("$string"."$char")}
             :set cont $key
         }
      }
:return $string}
This small function allows you to enter a string of up to 254 characters character by character. In this example, the input stops if the user presses the "Enter" key (Enter key code=$0D (13). Of course, character-by-character input allows you to use any other restrictions for the end of the input (for example, another ending character or the number of characters entered), which allows you to configure the input most flexibly.
It can be supplemented with different buns with instant verification of the entered characters, limit the length of the generated string, etc...


But, if you need it easier and faster, you can use such a feature: https://forum.mikrotik.com/viewtopic.php?t=135112
:local input do={:put $1; :return;}
:local login [$input "Enter login:"]
:local password [$input "Enter password:"]
:put "Login is [$login] and password is [$password]"
The trick is that it is empty: return from the Terminal always prompts you to enter a value. The end of the input is necessarily the "Enter" key.The only inconvenience will be the output of the word "value:" as an invitation before entering, but if it's not annoying, then everything works fine.
It is convenient to use from interactive scripts configuration settings, etc...


Another possibility has appeared in the Router OS 7.11 - the use of :terminal ask. This new command is devoid of the inconvenience associated with the output of the prompt to enter the value :value. The end of the input is also necessarily the "Enter" key.
:global Answer [:terminal/ask "Do you agree to use Router OS 7?"]
:put $Answer
Well, or something like that (for example):
{
:global Answer []
:while ($Answer!="yes") do={
:set Answer [:terminal/ask "Do you agree to use Router OS 7?"]
}
}
You can also specify any input prompt if you use the "preinput" parameter:
:global userinput [/terminal/ask preinput="preinput>" prompt="Some text that in prompt"]
 
User avatar
Sertik
Member
Member
Topic Author
Posts: 448
Joined: Fri Sep 25, 2020 3:30 pm
Location: Russia, Moscow

Re: New command in RouterOs 7

Fri Sep 08, 2023 3:24 pm

I wrote a short article for the Russian-speaking audience on the new commands of the scripting language in the Router OS based on the materials of this topic. I hope I didn't mix anything up. I also thanked our respected gurus Rextended and Amm0 in the article for their help, explanations and examples of scripts.

https://habr.com/ru/articles/759564/
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Fri Sep 08, 2023 4:20 pm

Thanks ;)
 
User avatar
diamuxin
Member
Member
Posts: 323
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: New command in RouterOs 7

Sat Sep 09, 2023 9:13 pm

/console/inspect - this is an "easter egg" – but I have an partial example of usage here:
viewtopic.php?t=175564&hilit=%2Fconsole ... ct#p966543
Hi @Amm0, Is it possible to dump the command list (/console/inspect) in a file for future reference?

Thanks.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Sat Sep 09, 2023 9:23 pm

/console/inspect - this is an "easter egg" – but I have an partial example of usage here:
viewtopic.php?t=175564&hilit=%2Fconsole ... ct#p966543
Hi @Amm0, Is it possible to dump the command list (/console/inspect) in a file for future reference?

Let's not forget there is a 4K file limit, so while script can get all commands to memory. Writing it out gets trickier...
viewtopic.php?t=197190#p1008826

I'll start that script, and mull how to get it disk somehow. It takes a few hours to run actually.
 
User avatar
diamuxin
Member
Member
Posts: 323
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: New command in RouterOs 7

Sat Sep 09, 2023 9:37 pm

So, to keep it short, if I just want to get information about a specific command, for example "/ip/firewall", it would be something like this?
:put [/console/inspect as-value request=syntax path="/ip/firewall/"]

I've tried it and it doesn't work
Can you give me an example please?

Thanks
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Sat Sep 09, 2023 10:27 pm

Reflections on /console/inspect...

If you start at request= <tab> you get the gist of what's possible:
/console/inspect request=      
child     completion     error     highlight     self     syntax   

In request=syntax, path= needs to be set. So the main trick is path= is CLI list... The logic is "metadata"/information about commands, not actually commands, so you need commas in path= as that's how the CLI takes a list.

So to get the options for /ip/address, it looks like:
/console/inspect request=syntax path=ip,address

Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL   SYMBOL-TYPE  N  NON  TEXT                                                                    
syntax           collection   0  yes                                                                          
syntax  ..       explanation  1  no   go up to ip                                                             
syntax  add      explanation  1  no   Create a new item                                                       
syntax  comment  explanation  1  no   Set comment for items                                                   
syntax  disable  explanation  1  no   Disable items                                                           
syntax  edit     explanation  1  no                                                                           
syntax  enable   explanation  1  no   Enable items                                                            
syntax  export   explanation  1  no   Print or save an export script that can be used to restore configuration
syntax  find     explanation  1  no   Find items by value                                                     
syntax  get      explanation  1  no   Gets value of item's property                                           
syntax  print    explanation  1  no   Print values of item properties                                         
syntax  remove   explanation  1  no   Remove item                                                             
syntax  reset    explanation  1  no                                                                           
syntax  set      explanation  1  no   Change item properties             


And you can the properties by adding a "/set" to the path (again using commas):
/console/inspect request=syntax path=ip,address,add

Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL     SYMBOL-TYPE  NESTED  NONORM  TEXT                                   
syntax             collection        0  yes                                            
syntax  address    explanation       1  no      Local IP address                       
syntax  broadcast  explanation       1  no      Broadcast address                      
syntax  comment    explanation       1  no      Short description of the item          
syntax  copy-from  explanation       1  no      Item number                            
syntax  disabled   explanation       1  no      Defines whether item is ignored or used
syntax  interface  explanation       1  no      Interface name                         
syntax  netmask    explanation       1  no      Network mask                           
syntax  network    explanation       1  no      Network prefix                  



There are few more request= things too. The main one is request=child – this one is useful to know what the "command tree" looks like – that the one used in the larger script to export an abstractly, an AST ("abstract syntax tree"). Again it use the path= with CLI list formatting...

So with no path=, it's the top of the tree. If the "type" is "child", it means there might be children in AST request=child tree, and you use "name" in the another call to /console/inspect with that child name appended in "path=".
/console/inspect request=child           
         
Columns: TYPE, NAME, NODE-TYPE
TYPE   NAME           NODE-TYPE
self   root           path     
child  beep           cmd      
child  blink          cmd      
child  certificate    dir      
child  console        dir      
child  container      dir      
child  convert        cmd      
child  delay          cmd      
child  disk           dir      
child  do             cmd      
child  dude           dir      
child  environment    dir      
child  error          cmd      
child  execute        cmd      
child  file           path     
child  find           cmd      
child  for            cmd      
child  foreach        cmd      
child  global         cmd      
child  if             cmd      
child  import         cmd      
child  interface      path     

/console/inspect request=child path=ip,address 

Columns: TYPE, NAME, NODE-TYPE
TYPE   NAME     NODE-TYPE
self   address  dir      
child  add      cmd      
child  comment  cmd      
child  disable  cmd      
child  edit     cmd      
child  enable   cmd      
child  export   cmd      
child  find     cmd      
child  get      cmd      
child  print    cmd      
child  remove   cmd      
child  reset    cmd      
child  set      cmd      

/console/inspect request=child path=ip,address,set

Columns: TYPE, NAME, NODE-TYPE
TYPE   NAME       NODE-TYPE
self   set        cmd      
child  address    arg      
child  broadcast  arg      
child  comment    arg      
child  disabled   arg      
child  interface  arg      
child  netmask    arg      
child  network    arg      
child  numbers    arg      


request=self but largely same request=child...
/console/inspect request=self path=ip

Columns: TYPE, NAME, NODE-TYPE
TYPE   NAME          NODE-TYPE
self   ip            path     
child  address       dir      
child  arp           dir      
child  cloud         dir      
child  dhcp-client   dir      
child  dhcp-relay    dir      
child  dhcp-server   dir      
child  dns           dir      
child  firewall      dir      
child  hotspot       dir      
child  ipsec         dir      
child  kid-control   dir      
child  neighbor      dir      
child  packing       dir      
child  pool          dir      
child  proxy         dir      
child  route         dir      
child  service       dir      
child  settings      dir      
child  smb           dir      
child  socks         dir      
child  ssh           dir      
child  tftp          dir      
child  traffic-flow  dir      
child  upnp          dir      
child  vrf           dir      
child  export        cmd      



Another one is request=completion. This using "input=" as a proxy for what someone would type at the command line. So if we want to know what options /console/inspect ITSELF offered for the request=... the following get same list as top of this post:

/console/inspect request=completion input="/console/inspect request="

Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT
TYPE        COMPLETION  STYLE        OFFSET  PREFERENCE  SHOW  TEXT                         
completion              none             25  -1          no    whitespace                   
completion              none             25  64          no                                 
completion  [           syntax-meta      25  75          no    start of command substitution
completion  (           syntax-meta      25  75          no    start of expression          
completion  $           syntax-meta      25  75          no    substitution                 
completion  "           syntax-meta      25  75          no    start of quoted string       
completion  self        none             25  96          yes                                
completion  child       none             25  96          yes                                
completion  completion  none             25  96          yes                                
completion  highlight   none             25  96          yes                                
completion  syntax      none             25  96          yes                                
completion  error       none             25  96          yes              

Some more examples of request=completion ...

/console/inspect request=completion input="/ip/add" 

Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT
TYPE        COMPLETION  STYLE        OFFSET  PREFERENCE  SHOW  TEXT                    
completion  address     dir               4  96          yes   Address management      
completion  /           dir               7  95          yes   top of command hierarchy
completion              none              7  -1          no    whitespace              
completion  {           syntax-meta       7  40          no    start of command block  
completion  ;           syntax-meta       7  40          no    end of command          

/console/inspect request=completion input="/ip/addr/set "
Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT
TYPE        COMPLETION  STYLE        OFFSET  PREFERENCE  SHOW  TEXT                                   
completion  !           none             13  80          no    whitespace                             
completion  address     arg              13  96          yes   Local IP address                       
completion  broadcast   arg              13  95          yes   Broadcast address                      
completion  comment     arg              13  96          yes   Short description of the item          
completion  disabled    arg              13  96          yes   Defines whether item is ignored or used
completion  interface   arg              13  96          yes   Interface name                         
completion  netmask     arg              13  95          yes   Network mask                           
completion  network     arg              13  96          yes   Network prefix                         
completion  numbers     arg              13  96          yes   List of item numbers                   
completion              none             13  64          no                                           
completion  [           syntax-meta      13  75          no    start of command substitution          
completion  (           syntax-meta      13  75          no    start of expression                    
completion  $           syntax-meta      13  75          no    substitution                           
completion  "           syntax-meta      13  75          no    start of quoted string                 
completion  *           none             13  -1          no    id prefix                              
completion  <number>    none             13  -1          no    decimal number       

/console/inspect request=completion input="set" path=ip,address

Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT
TYPE        COMPLETION  STYLE        OFFSET  PREFERENCE  SHOW  TEXT                  
completion  set         cmd               0          96  yes   Change item properties
completion              none              3          80  no    whitespace            
completion  ;           syntax-meta       3          40  no    end of command        

/console/inspect request=completion still support a path=, in additional the require input=. path= reflects what "directory" the CLI is at (e.g. similar to typing /ip/address<enter> and then doing "set" in a new line). So you can see input is a space " ", which is kinda weird, but your looking for command completion here...
/console/inspect request=completion input=" " path=ip,address,set   

Columns: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT
TYPE        COMPLETION  STYLE        OFFSET  PREFERENCE  SHOW  TEXT                                   
completion  !           none              1  80          no    whitespace                             
completion  address     arg               1  96          yes   Local IP address                       
completion  broadcast   arg               1  95          yes   Broadcast address                      
completion  comment     arg               1  96          yes   Short description of the item          
completion  disabled    arg               1  96          yes   Defines whether item is ignored or used
completion  interface   arg               1  96          yes   Interface name                         
completion  netmask     arg               1  95          yes   Network mask                           
completion  network     arg               1  96          yes   Network prefix                         
completion  numbers     arg               1  96          yes   List of item numbers                   
completion              none              1  64          no                                           
completion  [           syntax-meta       1  75          no    start of command substitution          
completion  (           syntax-meta       1  75          no    start of expression                    
completion  $           syntax-meta       1  75          no    substitution                           
completion  "           syntax-meta       1  75          no    start of quoted string                 
completion  *           none              1  -1          no    id prefix                              
completion  <number>    none              1  -1          no    decimal number     


I never really messed with request=highlight but gets the syntax formatting using similar path= and input= scheme as rest... And request=error – I don't know how it works.

All the /console/inspect things support an "as-value" to store array with data to a variable, but I skipped that since it easier to cut-and-paste without it here.
 
User avatar
diamuxin
Member
Member
Posts: 323
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: New command in RouterOs 7

Sat Sep 09, 2023 11:37 pm

A great masterclass!
Thank you very much for helping me to understand it.

BR.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Tue Jan 09, 2024 12:30 pm

Some useful to compare news on different versions....

rextended code

:global cmdtree do={
    :global cmdtree ; # declared again for the recursive call
    :local start    [:tostr $1]
    :local qpath    ""
    :local temp     ""
    :local spac     ""
    :local arrPath  [:toarray ""]
    :local arrDir   [:toarray ""]
    :local arrCmd   [:toarray ""]
    :local arrArg   [:toarray ""]
    :local arrUnknw [:toarray ""]
    :local argreq   [:toarray ""]
    :local currType ""
    :local currName ""
    :local currPrfx ""

    :if ($start != "") do={
        :for pos from=0 to=([:len $start] - 1) do={
            :set temp [:pick $start $pos ($pos + 1)]
            :if ($temp = "/") do={:set temp ","}
            :set qpath "$qpath$temp"
            :set spac "$spac "
        }
    }

    :local request  [/console/inspect request=child path=$qpath as-value]
    :foreach item in=$request do={
        :if (($item->"type") = "self") do={
            :set currPrfx ($item->"name")
        } else={
            :set currType ($item->"node-type")
            :set currName ($item->"name")
            :if ($currType = "path") do={
                :set arrPath ($arrPath,$currName)
            } else={
                :if ($currType = "dir") do={
                    :set arrDir ($arrDir,$currName)
                } else={
                    :if ($currType = "cmd") do={
                        :set arrCmd ($arrCmd,$currName)
                    } else={
                        :if ($currType = "arg") do={
                            :set arrArg ($arrArg,$currName)
                        } else={
                            :set arrUnknw ($arrUnknw,"$currType = $currName")
                        }
                    }
                }
            }
        }
    }

    :if ($start = "") do={:put "/" ; :set spac " "} else={:put $start}
    :foreach item in=$arrCmd do={
        :put "$spac$item"
        :set argreq [/console/inspect request=child path="$qpath,$item" as-value]
        :if (($argreq->"type") != "self") do={
            :foreach par in=$argreq do={
                :if (($par->"type") != "self") do={
                    :set currType ($par->"node-type")
                    :set currName ($par->"name")
                    :if ($currType = "arg") do={
                        :put "$spac(a) $currName"
                    } else={
                        :put "$spac(UNKNOW) $currType = $currName"
                    }
                }
            }
        } else={
            :put "$spac(no arg)"
        }
    }
    :foreach item in=$arrArg do={
        :put "(a) $item"
    }
    :foreach item in=$arrUnknw do={
        :put "$start/$item (UNKNOWN)"
    }
    :foreach item in=$arrPath do={
        $cmdtree ("$start/$item")
    }
    :foreach item in=$arrDir do={
        $cmdtree ("$start/$item")
    }
}

$cmdtree

For save results...
:execute "\$cmdtree" file="all_cmd_$[/system resource get version]"

$cmdtree accept path as parameter, both on /ip/address and ip,address format
Last edited by rextended on Tue Jan 09, 2024 9:57 pm, edited 2 times in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Tue Jan 09, 2024 1:41 pm

The file are too big for the forum, first 466 lines of all_cmd_7.13.1 (stable).txt

partial results code

/
 beep
 (a) as-value
 (a) frequency
 (a) length
 convert
 (a) from
 (a) from-scheme
 (a) to
 (a) to-scheme
 (a) transform
 (a) transform-scheme
 (a) value
 delay
 (a) delay-time
 deserialize
 (a) from
 (a) value
 do
 (a) command
 (a) if
 (a) on-error
 (a) while
 error
 (a) message
 execute
 (a) as-string
 (a) file
 (a) script
 find
 (a) from
 (a) in
 (a) key
 for
 (a) counter
 (a) do
 (a) from
 (a) step
 (a) to
 foreach
 (a) counter
 (a) do
 (a) in
 global
 (a) do
 (a) name
 (a) value
 grep
 (a) after
 (a) as-array
 (a) before
 (a) filename
 (a) pattern
 (a) script
 if
 (a) condition
 (a) do
 (a) else
 import
 (a) file-name
 (a) from-line
 (a) verbose
 jobname
 (no arg)
 len
 (a) value
 local
 (a) do
 (a) name
 (a) value
 nothing
 (no arg)
 onerror
 (a) do
 (a) error
 (a) in
 parse
 (a) value
 password
 (a) as-value
 (a) confirm-new-password
 (a) new-password
 (a) old-password
 pick
 (a) begin
 (a) counter
 (a) end
 ping
 (a) address
 (a) arp-ping
 (a) as-value
 (a) count
 (a) do-not-fragment
 (a) dscp
 (a) interface
 (a) interval
 (a) size
 (a) src-address
 (a) ttl
 (a) vrf
 (a) without-paging
 put
 (a) message
 quit
 (no arg)
 redo
 (no arg)
 resolve
 (a) domain-name
 (a) server
 (a) server-port
 retry
 (a) command
 (a) delay
 (a) max
 (a) on-error
 return
 (a) value
 rndnum
 (a) from
 (a) to
 rndstr
 (a) from
 (a) length
 serialize
 (a) to
 (a) value
 set
 (a) do
 (a) name
 (a) value
 time
 (a) command
 timestamp
 (no arg)
 toarray
 (a) value
 tobool
 (a) value
 toid
 (a) value
 toip
 (a) value
 toip6
 (a) value
 tonsec
 (a) value
 tonum
 (a) value
 tostr
 (a) value
 totime
 (a) value
 typeof
 (a) value
 undo
 (no arg)
 while
 (a) condition
 (a) do
 export
 (a) compact
 (a) file
 (a) hide-sensitive
 (a) show-sensitive
 (a) terse
 (a) verbose
 (a) where
/interface
          blink
          (a) numbers
          comment
          (a) comment
          (a) numbers
          disable
          (a) numbers
          edit
          (a) number
          (a) value-name
          enable
          (a) numbers
          find
          (a) where
          get
          (a) as-string
          (a) as-string-value
          (a) number
          (a) value-name
          monitor-traffic
          (a) append
          (a) as-value
          (a) do
          (a) duration
          (a) file
          (a) interface
          (a) interval
          (a) once
          (a) without-paging
          print
          (a) append
          (a) as-value
          (a) brief
          (a) count-only
          (a) detail
          (a) file
          (a) follow
          (a) follow-only
          (a) follow-strict
          (a) from
          (a) interval
          (a) oid
          (a) proplist
          (a) show-ids
          (a) stats
          (a) stats-detail
          (a) terse
          (a) value-list
          (a) where
          (a) without-paging
          reset
          (a) comment
          (a) disabled
          (a) l2mtu
          (a) mtu
          (a) name
          (a) numbers
          reset-counters
          (a) numbers
          set
          (a) comment
          (a) disabled
          (a) l2mtu
          (a) mtu
          (a) name
          (a) numbers
          export
          (a) compact
          (a) file
          (a) hide-sensitive
          (a) show-sensitive
          (a) terse
          (a) verbose
          (a) where
/interface/6to4
               add
               (a) clamp-tcp-mss
               (a) comment
               (a) copy-from
               (a) disabled
               (a) dont-fragment
               (a) dscp
               (a) ipsec-secret
               (a) keepalive
               (a) local-address
               (a) mtu
               (a) name
               (a) remote-address
               comment
               (a) comment
               (a) numbers
               disable
               (a) numbers
               edit
               (a) number
               (a) value-name
               enable
               (a) numbers
               export
               (a) compact
               (a) file
               (a) hide-sensitive
               (a) show-sensitive
               (a) terse
               (a) verbose
               (a) where
               find
               (a) where
               get
               (a) as-string
               (a) as-string-value
               (a) number
               (a) value-name
               print
               (a) append
               (a) as-value
               (a) brief
               (a) count-only
               (a) detail
               (a) file
               (a) follow
               (a) follow-only
               (a) follow-strict
               (a) from
               (a) interval
               (a) proplist
               (a) show-ids
               (a) terse
               (a) value-list
               (a) where
               (a) without-paging
               remove
               (a) numbers
               reset
               (a) clamp-tcp-mss
               (a) comment
               (a) disabled
               (a) dont-fragment
               (a) dscp
               (a) ipsec-secret
               (a) keepalive
               (a) local-address
               (a) mtu
               (a) name
               (a) numbers
               (a) remote-address
               set
               (a) clamp-tcp-mss
               (a) comment
               (a) disabled
               (a) dont-fragment
               (a) dscp
               (a) ipsec-secret
               (a) keepalive
               (a) local-address
               (a) mtu
               (a) name
               (a) numbers
               (a) remote-address
               unset
               (a) numbers
               (a) value-name
/interface/bonding
                  add
                  (a) arp
                  (a) arp-interval
                  (a) arp-ip-targets
                  (a) arp-timeout
                  (a) comment
                  (a) copy-from
                  (a) disabled
                  (a) down-delay
                  (a) forced-mac-address
                  (a) lacp-rate
                  (a) lacp-user-key
                  (a) link-monitoring
                  (a) mii-interval
                  (a) min-links
                  (a) mlag-id
                  (a) mode
                  (a) mtu
                  (a) name
                  (a) primary
                  (a) slaves
                  (a) transmit-hash-policy
                  (a) up-delay
                  comment
                  (a) comment
                  (a) numbers
                  disable
                  (a) numbers
                  edit
                  (a) number
                  (a) value-name
                  enable
                  (a) numbers
                  export
                  (a) compact
                  (a) file
                  (a) hide-sensitive
                  (a) show-sensitive
                  (a) terse
                  (a) verbose
                  (a) where
                  find
                  (a) where
                  get
                  (a) as-string
                  (a) as-string-value
                  (a) number
                  (a) value-name
                  monitor
                  (a) append
                  (a) as-value
                  (a) do
                  (a) duration
                  (a) file
                  (a) interval
                  (a) numbers
                  (a) once
                  (a) without-paging
                  monitor-slaves
                  (a) as-value
                  (a) bond
                  (a) duration
                  (a) freeze-frame-interval
                  (a) once
                  (a) without-paging
                  print
                  (a) append
                  (a) as-value
                  (a) brief
                  (a) count-only
                  (a) detail
                  (a) file
                  (a) follow
                  (a) follow-only
                  (a) follow-strict
                  (a) from
                  (a) interval
                  (a) proplist
                  (a) show-ids
                  (a) terse
                  (a) value-list
                  (a) where
                  (a) without-paging
                  remove
                  (a) numbers
                  reset
                  (a) arp
                  (a) arp-interval
                  (a) arp-ip-targets
                  (a) arp-timeout
                  (a) comment
                  (a) disabled
                  (a) down-delay
                  (a) forced-mac-address
                  (a) lacp-rate
                  (a) lacp-user-key
                  (a) link-monitoring
                  (a) mii-interval
                  (a) min-links
                  (a) mlag-id
                  (a) mode
                  (a) mtu
                  (a) name
                  (a) numbers
                  (a) primary
                  (a) slaves
                  (a) transmit-hash-policy
                  (a) up-delay
                  set
                  (a) arp
                  (a) arp-interval
                  (a) arp-ip-targets
                  (a) arp-timeout
                  (a) comment
                  (a) disabled
                  (a) down-delay
                  (a) forced-mac-address
                  (a) lacp-rate
                  (a) lacp-user-key
                  (a) link-monitoring
                  (a) mii-interval
                  (a) min-links
                  (a) mlag-id
                  (a) mode
                  (a) mtu
                  (a) name
                  (a) numbers
                  (a) primary
                  (a) slaves
                  (a) transmit-hash-policy
                  (a) up-delay
                  unset
                  (a) numbers
                  (a) value-name
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Tue Jan 09, 2024 6:50 pm

The file are too big for the forum, first 466 lines of all_cmd_7.13.1 (stable).txt
Does the entire command tree even fit in a 64k variable? What be interesting to see is the count of commands from various versions....

I have some JS code that generates a scheme for the REST API (viewtopic.php?t=199476&hilit=openapi). I had use JavaScript to call /console/inspect via REST since the variable size limited generating the scheme in RouterOS script... But perhaps JUST commands and attributes alone fit, so I could avoid the JavaScript in my "REST schema generator" at some point.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Tue Jan 09, 2024 9:33 pm

The function was created to save a file, to be taken outside the routerboard and then compared between those of different installed versions/packages.

It takes little to modify it and use it to create a variable.

vargen example code

:global cmdtreeVar do={
    :global cmdtreeVar ; # declared again for the recursive call
    :local ret      ""
    :local start    [:tostr $1]
    :local qpath    ""
    :local temp     ""
    :local spac     ""
    :local arrPath  [:toarray ""]
    :local arrDir   [:toarray ""]
    :local arrCmd   [:toarray ""]
    :local arrArg   [:toarray ""]
    :local arrUnknw [:toarray ""]
    :local argreq   [:toarray ""]
    :local currType ""
    :local currName ""
    :local currPrfx ""

    :if ($start != "") do={
        :for pos from=0 to=([:len $start] - 1) do={
            :set temp [:pick $start $pos ($pos + 1)]
            :if ($temp = "/") do={:set temp ","}
            :set qpath "$qpath$temp"
            :set spac "$spac "
        }
    }

    :local request  [/console/inspect request=child path=$qpath as-value]
    :foreach item in=$request do={
        :if (($item->"type") = "self") do={
            :set currPrfx ($item->"name")
        } else={
            :set currType ($item->"node-type")
            :set currName ($item->"name")
            :if ($currType = "path") do={
                :set arrPath ($arrPath,$currName)
            } else={
                :if ($currType = "dir") do={
                    :set arrDir ($arrDir,$currName)
                } else={
                    :if ($currType = "cmd") do={
                        :set arrCmd ($arrCmd,$currName)
                    } else={
                        :if ($currType = "arg") do={
                            :set arrArg ($arrArg,$currName)
                        } else={
                            :set arrUnknw ($arrUnknw,"$currType = $currName")
                        }
                    }
                }
            }
        }
    }

    :if ($start = "") do={:set ret ("$ret/\r\n") ; :set spac " "} else={:set ret ("$ret$start\r\n")}
    :foreach item in=$arrCmd do={
        :set ret ("$ret$spac$item\r\n")
        :set argreq [/console/inspect request=child path="$qpath,$item" as-value]
        :if (($argreq->"type") != "self") do={
            :foreach par in=$argreq do={
                :if (($par->"type") != "self") do={
                    :set currType ($par->"node-type")
                    :set currName ($par->"name")
                    :if ($currType = "arg") do={
                        :set ret ("$ret$spac(a) $currName\r\n")
                    } else={
                        :set ret ("$ret$spac(UNKNOW) $currType = $currName\r\n")
                    }
                }
            }
        } else={
            :set ret ("$ret$spac(no arg)\r\n")
        }
    }
    :foreach item in=$arrArg do={
        :set ret ("$ret(a) $item\r\n")
    }
    :foreach item in=$arrUnknw do={
        :set ret ("$ret$start/$item (UNKNOWN)\r\n")
    }
    :foreach item in=$arrPath do={
        :set ret ("$ret$[$cmdtreeVar ("$start/$item")]")
    }
    :foreach item in=$arrDir do={
        :set ret ("$ret$[$cmdtreeVar ("$start/$item")]")
    }
:return $ret
}

:put [:len [$cmdtreeVar]]
$cmdtreeVar accept path as parameter, both on /ip/address and ip,address format

Output is 972.386 Bytes (RouterOS 7.13.1 with routeros + user-manager without any wireless/wifi packages)
More than "virtual" 64K limit.
Last edited by rextended on Tue Jan 09, 2024 9:57 pm, edited 3 times in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12310
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: New command in RouterOs 7

Tue Jan 09, 2024 9:50 pm

I forgot:

Both $cmdtree and $cmdtreeVar accept path as parameter, both on /ip/address and ip,address format
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3828
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: New command in RouterOs 7

Fri May 31, 2024 8:31 pm

FWIW, I already had a GitHub project that compiled the REST schema, and as part of that there is an "inspect.json" that get generates with output of /console/inspect. I recently automated it all at GitHub, and put a tiny web page that has downloadable form of the "command schema":

https://tikoci.github.io/restraml

On the web page, I wrote a quick-and-dirty "diff tool" for output a recursive /console/inspect. So you can compare command difference in between various releases. Since it does this in the browser, it take may take a dozen seconds to show diffs.

And to also digress... There is a new [:convert from=byte-array] method in 7.15, I put a few examples here: viewtopic.php?t=57665#p1078218 – but it's useful to the /termina/inkey discussed above...
I'll digress a little from the main topic of the topic and give examples of the possibility of entering a line in the Terminal:
For /terminal/inkey, there is an handy method, in 7.15, to get the actual string of the char pressed, so you don't need to compare the ASCII int code. So if you run this code, and hit the letter "a", you can see you get the actual "a" back:
:put [/terminal/inkey]                                                   
# 97
:put [:convert from=byte-array to=raw {[/terminal/inkey]}]
# a

Who is online

Users browsing this forum: No registered users and 6 guests