目录
继续讲ros脚本基础知识,本章将讲ros运行符Operators,ros运算符主要包括
- 算术运算
- 关系运算
- 逻辑运行
- 位运算
- 连接符
- 其它
一、前言
ros运行符是其中一个很重要的角色,所以学好ros运算符很重要,用得比较多的还是关系、逻辑、连接符。所以这个是重点。每种运算符用在哪里,这里我简单说一下。
二、算术运算
算术运算主要是乘除加减,这个就不再说了吧,见下表所示:
运算符 说明 例子 "+" binary addition 二进制加法 :put (3+4);
"-" binary subtraction二进制减法,二元操作(即2个数) :put (1-6);
"*" binary multiplication二进制乘法 :put (4*5);
"/" binary division二进制除法 :put (10 / 2); :put ((10)/2)
"%" modulo operation取模 :put (5 % 3);
"-" unary negation一元取反,所谓的一元即是,只有一个数 { :local a 1; :put (-a); }
如果拿ppoe例子来说的话,算术运算用来计费挺好的,比如一定时间段的费用,主要是统计、结数等方面
三、关系运算
运算符 描述 例子 "<" 小于 :put (3<4);
">" 大于 :put (3>4);
"=" 等于 :put (2=2);
"<=" 大于或等于 ">=" 大于或等于
"!=" 不等于
关系运算主要是配合后面的条件判断、循环语句。比如检查包季pppoe账号到期时间,如果是1周内那每天打开,就强制转跳到账号即将到期的提示,并写上联系方式。
下面为脚本,为了方便理解,实现命令和代码部分我隐去了
# 如果用户即将到期了,就发送信息。1为需要发送,0表示还不到期
# 我这里设置为1,在实际中其实是结合freeRadius在认证用户部分触发的
:local IsSendMsg 1
:if ($IsSendMsg=1) do={
# ros配置命令,设置每天首次访问强制转跳,直至续费或到期停号
# 我这里方便,只做一个打印
:put "Account is about to expire, please renew"
}
执行效果:
[hua@MikroTik] > system script run t1
Account is about to expire, please renew
四、位运算
运行符 说明 例子 “~” 按位反。其实就是CCNA中所说的反掩码 :put (~0.0.0.0)
:put (~::ffff)
“|” 位或or运算。只有一位为1结果都为1,只有全部为0结果才为0 :put (192.168.88.0|0.0.0.255)
:put (2001::1|::ffff)
“^” 按位异或。 与OR相同,但如果两个位不相等,则每个位置的结果为“ 1”,如果相等则为“ 0” :put (1.1.1.1^255.255.0.0)
:put (2001::ffff:1^::ffff:0)
“&” 按位与。 如果第一和第二位为“ 1”,则每对结果为“ 1”。 否则结果为“ 0”。 :put (192.168.88.77&255.255.255.0)
:put (2001::1111&ffff::)
“<<” 左移给定的位数,不支持IPv6地址数据类型 :put (192.168.88.77<<8)
“>>” 按给定的位数右移,IPv6地址数据类型不支持 :put (192.168.88.77>>24)
位运算在开发中,有时用了也是比较多的,为了提高编写代码的效果,我们谢谢使用数字来表达选择或者状态,这样编程方式是很多人用的。
比如:
用3位二进制数表示用户的冻结、余额、线。第1位表示是否在线,第2位表示余额是否不够,第3位账号是否处冻结状态(处理特殊情况)。
如:
010:账号可用 用户余额充足 没有上线; 001表示:账号用用 余额不够,但是用户在线(前次检查余额是够,现在不够了),那么就是T他下线了;
按位返操作,在这里的应用。比如用户余额不足,他过一会儿充值了,那么你只需要做按位反操作即可
按位或:账号是否可用,只要账号冻结状态和余额一项不符合,则不能上网,那就用第2和第3位做或运算即可,第1个可以不看
...
五、连接符
当我们想把几个字符串或数组连接在一起的时候就需要连接符了。
操作符 说明 Example “.” 连接两个字符串 :put (“concatenate” . “ “ . “string”);
“,” 连接两个数组或将元素添加到数组 :put ({1;2;3} , 5 );
5.1 字符串连接
你时候需要把多个字符串连接起来,一起输出。有的初学者就疑问了,像上面例子我直接写在一起不就行了,搞得这么麻烦,上面例子是可以写在一起的,是的没错。但如果是变量的值+字符串连接呢?所以需要字符器连接符连在一起。
例子
# 查询用户余额,一般用local balance [/tool fetch xxx]
# 为了实验我这里直接写上去
:local balance 80
# 小括号不能省,会报错,因为这个涉及优先级
# 也可以写成 :put "your balance is:$balance"
:put ("your balance is:".$balance)
运行效果:
[hua@MikroTik] > system script run t1
your balance is:80
5.2 数组连接
数据连接使用的是豆号,在什么情况下要使用数组连接,当我们原数据不够用的时候添加多一个元素进去,变成新数组时才用到。
比如我们要获取指定在线用户基本和流量。那么在ros中要得到2个结果,需要分别执行2条命令才行
# 获取用户信息
:local usrInfo [ppp active print detail as-value where name=p11]
# 获取用户流量
:local userTraff [interface print stats as-value where name=<pppoe-p11>]
会得到2个数组,把2个数组可以连接起来或者再创建一个数组 可以使用命令 :put ($usrInfo,$userTraff)
创建一个名为t1的ros创建,添加如下内容:
# 获取用户信息
:local usrInfo [ppp active print detail as-value where name=p11]
# 获取用户流量
:local userTraff [interface print stats as-value where name=<pppoe-p11>]
:put ($usrInfo,$userTraff)
#执行效果为:
[hua@MikroTik] > system script run t1
.id=*80000000;address=10.10.1.250;caller-id=00:0C:29:CA:B0:A3;comment=;encoding=;
limit-bytes-in=0;limit-bytes-out=0;name=p11;service=pppoe;session-id=2165309440;
uptime=06:56:36;.id=*f00000;comment=;name=<pppoe-p11>;rx-byte=121168;rx-drop=0;
rx-error=0;rx-packet=984;tx-byte=128407;tx-drop=0;tx-error=0;tx-packet=309;tx-queue-drop=0
六、其它操作符
除了上面的运算符之外,还有其它运行符
运算符 说明 例子 “[]” command substitution. Can contain only single command line
命令替换。 只能包含一个命令行
:put [ :len "my test string"; ];
“()” sub expression or grouping operator
子表达式或分组运算符
:put ( "value is " . (4+5));
“$” substitution operator
获取变量值
:global a 5; :put $a;
“~” binary operator that matches value against POSIX extended regular expression
Print all routes which gateway ends with 202 /ip route print where gateway~"^[0-9 \\.]*202\$"
“->” Get an array element by key
通过key获取数组元素
[admin@x86] >:global aaa {a=1;b=2} [admin@x86] > :put ($aaa->"a") 1 [admin@x86] > :put ($aaa->"b") 2
这些之前的章节已经讲过了,我在这里就不重复了