目录

一、前言

二、命令字Command word

2.1  说明

2.2 例子

三、属性词 Attribute word

3.1 说明

3.2 例子

四、查询词Query word

五、routeros模块query方法查询

5.1 query方法说明

5.2 例子

六、其它

七、注意事项

7.1  用api执行脚本返回值为空的问题

7.2 用api执行脚本中有fetch命令问题

前章我讲了如何使用python的routeros模块连接ros api执行ros命令,本章将讲解ros api的语法是怎使用的,并结合python一起做例子。

有兴趣的可以提前看一下ros api官方文档

一、前言

ros api官言文档只是简单地讲解了api的用法 ,最后给了一堆开发语言的例子,对于编程基础很弱的初学者一脸懵进来,一脸灰出去。所以我觉得很我必要写一下。

后面写的例子都是基于python routeros模块来操作ros api的

相关ros api知识可以看官网 mikrotik API 使用说明,我这里使用的是python routeros模块进行开发,目前最新稳定版本为0.1.1

二、命令字Command word

2.1  说明

句子中的第一个单词必须是命令,然后是属性单词和零长度单词或终止单词。命令字的名称应以“ /”开头。命令名紧随CLI,用‘/’代替空格。有一些特定于API的命令。

命令字的结构严格按顺序排列:

  • 编码长度
  • 内容前缀/
  • CLI转换的命令

简单来说:命令行写的命令是用空格的,现在改为斜杠“/”代替空格即可

ps:值得注意的是在ros api支持菜单级命令,脚本命令是不支持的,比如像大中小括号,冒号开头的命令,是不能直接写在命令中的。

如果非要写可以写在  /System Scripts  中,或者ppp的Profile的Scripts属性中

ros api执行的命令结果会和菜单命令有些出入,需要注意一下。

2.2 例子

创建一个名为t1的python文件,如果不懂可以看回前章《RouterOS py api(四): python通过ros aip执行命令

from routeros import *
import prettyprinter

# 使用API方式登录routerOS,调用routeros login()
ros = login("hua", "123", "192.168.3.6")
# ros对象执行相关命令返回元组
tup1 = ros("/ip/address/print")
# 输出整个返回结果
# prettyprinter.pprint(tup1)
print("所使用的IP地址为:")
# 拆解
for dict in tup1:
    print(dict["address"])

ros.close()

执行结果

所使用的IP地址为:
192.168.2.6/24
192.168.128.6/24
192.168.3.6/24
10.10.10.2/32

三、属性词 Attribute word

3.1 说明

每个命令字都有自己的属性字列表,具体取决于内容。

属性词结构按以下顺序由5部分组成:

  • 编码长度
  • 内容前缀等于符号– =
  • 属性名称
  • 分隔等号– =
  • 属性值(如果有)。该属性可能没有值

例子

=address=10.0.0.1

=name=iu=c3Eeg

=disable-running-check=yes

说白就就意思就是: 如果是属性前面要加等于“=”号,属性值也用“=”号赋,格式就是

“=属性名=[值]”

# []号表示可以为空 

值得注意的是:当使用print命令有属性的时候,不能使用 “=属性名=[值]” 这样方式,将在第4小节进行讲解。

3.2 例子

比如找到项目号为0你在线用户,创建一个新的python,名字随便,输入如下代码

from routeros import *

# 使用API方式登录routerOS,调用routeros login()
ros = login("hua", "123", "192.168.3.6")
# ros对象执行相关命令返回元组
result = ros("/ppp/active/get", '=number=0', '=value-name=name')
print(result)
ros.close()

运行结果为

({‘ret’: ‘p11’},)

四、查询词Query word

句子可以具有限制其范围的其他查询参数。

查询词以“?”开头。
查询词的顺序很重要。 从第一个单词开始评估查询。
将对列表中的每个项目评估查询。 如果查询成功,则处理项目,如果查询失败,则忽略项目。
使用一堆布尔值评估查询。 最初,堆栈包含无限数量的“ true”值。 评估结束时,如果堆栈包含至少一个“假”值,则查询失败。

查询词根据以下规则进行操作:

查询 说明 例子
?name

pushes ‘true’ if item has value of property name, ‘false’ if it does not.

如果项目具有属性名称的值,则推“true”,否则则为“false”。

查看包含属性为 address 

print(ros(“/ppp/active/print”, ‘?address’))

?-name

pushes ‘true’ if item does not have value of property name, ‘false’ otherwise.

如果项目不具有属性名称的值,则推送“true”,否则推送“false”。

查看不包含属性 address 的项目

print(ros(“/ppp/active/print”, ‘?-address’))

?name=x
?=name=x

pushes ‘true’ if property name has value equal to x, ‘false’ otherwise.

如果属性名称的值等于x,则推送’true’,否则推送’false’。

查看名字为p11的在线用户

print(ros(“/ppp/active/print”, ‘?name=p11’))

 

?<name=x

 

pushes ‘true’ if property name has value less than x, ‘false’ otherwise.

如果属性名称的值小于x,则推送’true’,否则推送’false’。

查看接收流量小于100M的,默认是字节所以要加多6个0
print(ros("/interface/print", '?<rx-byte=100000000'))
?>name=x

pushes ‘true’ if property name has value greater than x, ‘false’ otherwise.

如果属性名称的值大于x,则推送’true’,否则推送’false’。

查看接收流量大于100M的,默认是字节所以要加多6个0
print(ros(“/interface/print”, ‘?>rx-byte=100000000’))
?#operations 将操作应用于堆栈中的值。

  • 操作字符串从左到右求值。
  • 十进制数字序列后跟任何其他字符或单词结尾被解释为堆栈索引。 最高值的索引为0。
  • 索引后跟一个字符,将值的副本推送到该索引处。
  • 单词结尾处的索引将所有值替换为该索引处的值。
  • ! 字符用相反的值代替最高值。
  • & 弹出两个值并推送逻辑’and’操作的结果。
  • | 弹出两个值并推送逻辑“或”运算的结果。
  • . 在索引之后什么也不做。
  • . 之后另一个字符将复制最高价值。
例子我这里就不讲了

五、routeros模块query方法查询

要查询操作除了上面的之外,还要以直接使用python routeros模块query方法。

5.1 query方法说明

根据python routeros模块说明文档,指定属性可以使用如下

  • query.has(*args)   查询某个属性名字是否存在,如 ros.query(“/ppp/active/print”).has(“uptime”)
  • query.hasnot(*args) 查询不包含某属性名字的。
  • query.equal(**kwargs) 查询属性名为某个值项目
  • query.lower(**kwargs) 查询小于某个属性值的项目
# 查上传流量小于100M的项目
query = {'rx-byte': (1024*1024*100)}
result = ros.query("/interface/print").lower(**query)
print(result)
  • query.greater(**kwargs) 查询大于某个属性值的项目

Python中,(*)会把接收到的参数形成一个元组,而(**)则会把接收到的参数存入一个字典

5.2 例子

我就拿一个典型的例子,查询在线用户p11时长,如果用命令执行是这样的

# 查看用户p11在线时长
[hua@MikroTik] > :put [ ppp active get [find name=p11] value-name=uptime ]  
01:07:37

这里用到get和find的的组合,因为有小括号,我们不能直接转ros api,所以可以分2次执行;先执行find再执行get

from routeros import *

# 使用API方式登录routerOS,调用routeros login()
ros = login("hua", "123", "192.168.3.6")
# ros对象执行相关命令返回元组
resultUserID = ros("/ppp/active/find", '=where=name=p11')
resultUserUptime = ros("/ppp/active/get", '=number=0', '=value-name=uptime')
print(resultUserUptime[0]['ret'])
ros.close()

执行结果为:

01:18:00

上面结合有点麻烦,可以直接使用query的查询功能,代码如下:

from routeros import *

# 使用API方式登录routerOS,调用routeros login()
ros = login("hua", "123", "192.168.3.6")
# ros对象执行相关命令返回元组
resultUserUptime = ros.query("/ppp/active/print").equal(name="p11")
print(resultUserUptime[0]['uptime'])
ros.close()

执行结果为:1h22m12s

六、其它

其它部分用得比较少,有兴趣的可以看一下ros api 官方文档,相信你现在应该有能力看懂了

七、注意事项

7.1  用api执行脚本返回值为空的问题

在API执行脚本的时候,要返回结果给python用“:return” ,不能使用“:put”,否则返回值为空!

7.2 用api执行脚本中有fetch命令问题

当ros脚本把 fetch命令结果赋值给变量,会变成空值,而使用ros命令执行则表示正常。所以当脚本中有fetch要特别注意。

本文地址:https://blog.csdn.net/hualinux/article/details/110391591