Hi,
As I know, there are four good ways of processing complex print outputs from Mikrotik: using the Mikrotik API, or using the ‘print detailed’, ‘print terse’ and ‘print as-value’ commands.
I use Fabric (http://www.fabfile.org/) to manage Mikrotik hosts. It uses SSH as backend: so, I rely on ‘print’ commands over SSH to get more complex info from my Mikrotik hosts. /Iso I want a good way of process the outputs of print commands.
Some points:
- Print parsing library???
I checked Pypy (Python package repository) for a lib that parses the Mikrotik ‘print’ commands. I only find libraries (some of them seems to be very good) that parse command outputs via the Mikrotik API. I did not find any library that can parse print commands.
Do you know any library for this? Or any implementation in other programing language?
- ‘print’ command parse problems
As I did not find a library for finding print commands via SSH, I’m implementing one.
However, I am having some problems with the print commands.
2.1) ‘print terse’ do not escape spaces
This observation is also found in a post from @alcohol: http://forum.mikrotik.com/t/interface-type-has-a-space-and-is-unquoted-bug/109163/1
I also discovered that ‘print detail’ can not escape spaces in some cases.
2.2) ‘print terse’ do not escape the equal ‘=’ char
The problem 2.1 can be solved if we consider that spaces can have different meanings in a ‘print terse’ output: key-value separators or spaces inside a value. Also, we need also to consider that empty values have special representation in ‘print terse’ (‘“”’).
For example:
key1=value1 key2=my value 2 key3=“”
Means (in a Python notation):
[(‘key1’, ‘value1’), (‘key2’, ‘my value 2’), (‘key3’, ‘’)]
Or (another notation):
key1=“value1” key2=“my value 2” key3=“”
But I still have problems with the ‘=’ char. For example, if I create the interface:
/interface vlan add name="teste mtu=1400" vlan-id=10 interface=ether1
The print terse command will return:
[admin@router] > /interface print terse where type=vlan
0 R name=teste mtu=1400 type=vlan mtu=1500 actual-mtu=1500 l2mtu=1522 mac-address=00:0C:42:74:99:F1 fast-path=no last-link-up-time=feb/15/2018 06:20:59 link-downs=0
So my parser cannot parse mtu (mtu=1400 or mtu=1500???).
2.3) Problems with ‘print as-value’ and ‘print detail’
A similar problem occurs in ‘print as-value’ when using the ‘;’ char:
[admin@router] > /interface vlan add name="teste mtu=1400" vlan-id=10 interface=ether1
[admin@router] > :put [/interface print as-value where type=vlan]
.id=*15;actual-mtu=1500;comment=;l2mtu=1522;mac-address=00:0C:42:74:99:F1;name=teste;mtu=1400;type=vlan
Again, problem while parsing mtu: the parser thinks ‘mtu=1400’ while it’s 1500.
A similar problem can occur when using ‘print detail’:
[admin@router] > /interface vlan add name="teste\" mtu=\"1400" vlan-id=10 interface=ether1
[admin@router] > /interface print detail where type=vlan
Flags: D - dynamic, X - disabled, R - running, S - slave
0 R name="teste" mtu="1400" type="vlan" mtu=1500 actual-mtu=1500 l2mtu=1522 mac-address=00:0C:42:74:99:F1 fast-path=no
last-link-up-time=feb/15/2018 06:20:59 link-downs=0
Again, I can’t parse mtu since it seems to be 1400 and 1500 at the same time.
How should I parse ‘print terse’, ‘print as-value’ and ‘print detail’ commands in these cases? It is a bug in these commands?