Bro脚本语法4-声明和语句(Declarations and Statements)
Bro脚本语法4-声明和语句(Declarations and Statements)
@(教程)[Bro]
Declarations
Name | Description |
---|---|
module | 改变当前模块 |
export | 从当前模块导出定义 |
global | 声明一个全局变量 |
const | 声明一个全局常量 |
type | 声明一个一用户自定义类型 |
redef | 重新定义一个全局值或者扩展一个用户自定义类型 |
function/event/hook | 声明一个 function/event/hook |
Statements
Name | Description |
---|---|
local | 声明一个局部变量 |
add, delete | 添加或删除元素 |
打印到标准输出或文件 | |
for, while, next, break | 遍历所有容器的元素(for), 条件循环(while). |
if | 表达式bool条件判断执行 |
switch, break, fallthrough | 计算表达式和匹配值执行语句 |
when | 异步执行 |
event, schedule | 调用或调度的事件处理程序 |
return | 从 function, hook, 或event 处理程序返回 |
声明
不能在 function, hook, event 处理函数中使用声明
必须在语句之前使用声明
module
关键字module 用于改变当前的module,这会影响任何随后全局标识符作用范围
例子:
module mymodule
如果一个全局的定义(global)声明在module的后面,那他的作用域在Bro脚本结束的地方或者在下一个module声明的位置,如果一个全局的声明在module的后面,但是在export 语句块中,那么它的作用域将扩展到最后一个load的bro脚本结束,但是在其他的module中它必须通过命名空间操作符(::)来进行引用
在一个bro脚本中,可以有多个module声明,同一个module也可以写在多个不同的bro脚本中
export
export 语句块将当前module中的一个或者多个声明(不能将语句块写在其中)导出,在其他module中,这些全局标识通过操作符”(::)”变得可见
例子:
export {redef enum Log::ID += {LOG};type Info: record {ts: time &log;uid: sting &log;};const conntime = 30sec &redef;}
注意,在导出块中括号是必须的,而且这个语句块也不需要用分号结束
global
声明一个全局变量
如果在声明的时候不指定类型,那么一定要赋一个初值,bro会实现类型推断,否则就一定要指定类型,或者在类型不能够准确推断的时候,也需要指定类型,例:
global pi = 3.14;
global host: set[addr];
global ciphers:table[sting] of sting = table();
在function ,event ,hook 外面的变量通常都需要用global 关键字(或者使用const 关键字);
在function ,event,hook 处理程序里面则不允许使用这个关键字,另外function 类型(不是函数体)也是可以通过global 关键字声明的.
global 关键字声明的变量作用域从声明的地方开始,到载入的脚本结束(同时,查看module 一节中的描述,当mudule改变的时候,对变量生命周期的改变)
const
const 用于声明一个常量
要求在声明的时候赋初值,同样的,类型可以被推断也可以准确指定
const pi = 3.14;
const ssh_port: port = 22/tcp;
常量的值不可以被改变,唯一的例外是当它是一个全局的常量同时含有 &redef 属性的时候,但是及时这样,他的值只能用 redef 来修改
常量如果定义在function,event, hook中,那么他的作用域就在处理函数内,否则它就是全局的。
注意到const 不能再被local 或者 global 修饰
type
type 关键字用于声明一个用户自定义的类型,新的类型将拥有全局的作用域,也可以用在任何内建类型出现的地方
type 关键字通常被用于定义 record 或者 enum , 当然在处理复杂类型的时候也很有用
例子:
type mytype:table[count] of table[addr,port] of string;
global myvar: mytype;
redef
有三种方式来使用redef :
用于改变全局变量的值(含有&redef 属性的变量)
用来扩展 record 类型或者 enum 类型
用来明确指定一个新的event处理函数替代之前所有的处理函数
如果你使用 “redef” 来改变一个全局变量(global 或者 const ),那么这个变量需要有&redef 属性,如果要修改的变量是 table,set,或者是pattern,就必须使用 +=操作符来添加新成员,否则直接用=号的话将会分配一个新的值,如果操作的对象是 table 或者set,可以使用-=操作符来移除已有的元素,其他情况下,你要通过=号来重新赋值,例:
redef pi = 3.14;
如果你用redef 来扩展 record 或者 enum,那么你必须使用 +=操作符,对于enum来说,你可以添加更多的枚举常量,对于record ,你可以添加更多的record字段,这时候,通过redef添加的字段,必须含有 &optional 或者 &default 属性,例:
redef enum color += {Blue,Red};
redef record MyRecord += {n2:int &optional;s2:string &optional;};
如果你使用redef 来替换event的处理函数,之前的函数将被完全移除(这个语句后的子event处理函数不会受到影响),语法和常规的event 处理函数的定义完全一样除了前面加了 ”redef“:
redef event myevent(s:string) {print "Redefined",s;}
function/event/hook
参考数据类型一节
语句(Statement)
除了在 function , hook ,event 处理函数中,Statement 只可以出现在所有级联载入(loaded)的Bro 脚本的所有全局声明的后面
所有的Statement必须使用分号结束,单独的语句可以分多行;
Bro 支持的 Statement
add
添加元素到set中
local muset:set[string];
add myset["test"];
break
用于 switch, for, while 语句中
delete
用于从 set 或者 table 中移除元素,或者移除record中具有&optional 属性的字段
local myset = set("this","test");
local mytable = table(["key1"] = 80/tcp.["key2"] = 53/udp);
local myrec = myRecordType($a = 1,$b = 2);delete myset["test"];
delete mytable["key1"];delete myrec$b;
event
用于立即触发一个event处理函数
event myevent("test",5);
fallthrough
用于在swith语句中的case块的尾部,指示执行下一个case 或者 跳到default 标签
for
迭代 string,set,vector,或者table 中的每一个元素并循环执行语句(注意set或者table 中的元素顺序是不确定的),如果元素为空,则不会循环
对于每个迭代对象,如果迭代对象是string,或者是set会分配一个循环变量保存循环中的元素,如果是vector或者是table 的话,将会是一个索引(index).
如果表达式含有多个索引的 table或者是set,,那么循环变量需要是括号内用分号分割的列表
注意 for中的循环变量不能是全局的,而且也不需要在for语句之前提前声明,他的类型会自动推断
同时,也不要在循环语句中添加或删除元素,不然会发生未定义的行为
break 语句 可以立即终止for 循环,next 语句可以用于跳过继续执行
local myset = set(80/tcp,81/tcp);
local mytable = table([10.0.0.1,80/tcp]="s1",[10.0.0.2,81/tcp]="s2"};for (p in myset)print p;
for ([i,j] in mytable) {if(mytable[i,j] == "done")break;if(mytable[i,j] == "skip")next;print i,j;
}
if
判读一个返回bool的表达式,执行语句
if (x == 2) print "x is 2";
同时,支持 else 语法
if (x == 2)print "x is 2";
else print "x is not 2";
local
声明一个本地变量,可以通过初始化值自动推断类型,否则要明确指定类型
local x1 = 5.7;
local x2:double ;
local x3:double = 5.3;
hook ,event,function 处理函数中,要求使用local 关键字来声明变量(除了const 声明和 for 语句中的隐式声明)
local 变量的作用域就仅限于声明的function,event,hook 处理函数中
next
用于 for 和 while 循环中,跳过语句继续执行循环
print
带一个逗号分割的列表表达式,所有表达式将会转换为stirng 并被打印
print 3.14;
print "Results:",x,y;
默认是打印到标准输出,如果第一个表达式是 file 类型,那么就会写到文件中去
如果string 中含有不可打印的字符,那么会被转换成对应的转义字符打印
对于string 的格式化,参考内建函数 fmt (base/bif/bro.bif.bro)
return
用于立即退出function,hook或者event处理函数,在function中如果存在返回值,将明确返回一个表达式或值,在hook和event中不会返回任何值,
function my_func(): string
{return "done";
}event my_event(n:count)
{if(n == 0) return;print n;
}
return 语句和 when 语句搭配使用,延时return , 当某个条件满足的时候才return ,或者超时return
global X:table[string] of count;function a() :count{return when ("a " in X){return X["a"];}timeout 30 sec{return 0;}}event bro_init(){when ( a() == 42)print "expected result";print "Waiting for a() to return....";X["a"] = 42;}
schedule
通过 指定 interval类型的时长延时触发event
schedule 30sec {myevent(x,y,z)};
注意这里大括号是必须的
schedule 表达式会返回一个timer类型的数据,但是一般不用
switch
跳转和匹配语句,匹配不到执行default,没有default 则什么也不执行
所有标签的类型必须和表达式的返回值一致
例(假设get_day_of_week返回一个string)
switch get_day_of_week(){case "Sa","Su":print "weekend";fallthrough;case "Mo", "Tu", "We", "Th", "Fr":print "valid result";break;default:print "invalid result";break;}
一个case标签可以匹配多个用逗号分割的表达式
标签必须是常量表达式
每个标签都必须使用 break,fallthrough,return 中的一个结束(return 只能用于function,hook,event中)
大括号是必须的
when
计算一个返回bool的表达式,当返回真或者表达式有效的时候,执行指定的语句
when ( (local x = foo()) && x == 42)print x;
如果指定了timeout,那么在指定时间内不能返回T,则执行timeout 语句块
when ( (local x = foo()) && x == 42 )print x;
timeout 5sec {print "timeout";
}
timeout 语句块中大括号是必须的
when 语句中可以进行变量的声明
when 语句中可以包含异步函数调用比如lookup_hostname(事实上,这也是这种函数唯一可以被调用的地方),也可以包含普通的函数,当一个异步函数被调用,Bro会继续执行when下面的语句块,当函数返回的时候,Bro才会计算when 语句块中的结果,return 章节介绍了如何创建一个异步函数
while
while 条件循环语句
break 语句可以随时终止while循环
next 语句会跳过本次循环继续执行
local i = 0;while ( i < 5 )print ++i;while ( some_cond() ){local finish_up = F;if ( skip_ahead() )next;if ( finish_up )break;}
compound statement
复合语句
通过大括号封装一个或多个语句
大括号语句都需要用分号来结束,但是括号外不需要分号
复合语句通过for,while,if, when 执行多条语句
if ( x == 2 ) {print "x is 2";++x;
}
null statement
空语句,只有一个分号的语句
if ( x == 2 );
Bro脚本语法4-声明和语句(Declarations and Statements)相关推荐
- Lua脚本语法说明(修订)
Lua脚本语法说明(增加lua5.1部份特性) Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了.估计看完了,就懂得 ...
- linux中的sh脚本语法
linux中的sh脚本语法 玩linux都知道sh脚本的方便,但如何编写sh脚本却是像我这样的新手和菜鸟的难题.能不能编写得出来是一回事,了不了解又是另一回事.抱着好好学习,天天向上的精神,大家有空就 ...
- 2.5 Bro脚本入门
基于Bro 2.5.3 文档,按照原文结构整理,非原文翻译,建议阅读英文文档后阅读,如有错误请不吝指出. 原文地址:https://www.bro.org/sphinx/scripting/index ...
- ubuntu中的fi语法_Shell脚本语法--if/then/elif/else/fi
Shell脚本语法--if/then/elif/else/fi 和C语言类似,在Shell中用if.then.elif.else.fi这几条命令实现分支控制.这种流程控制语句本质上也是由若干条Shel ...
- GBase 8s SQL 指南:语法————2.2 SQL 语句
ALTER ROUTINE 语句 使用 ALTER ROUTINE 语句更改先前定义的用户定义的例程(UDR)的例程修饰符或路径名.该 语句是 SQL ANSI/ISO 标准的扩展. 语法 元素 ...
- SQL语法基础之ALTER语句
SQL语法基础之ALTER语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看ALTER的帮助信息 mysql> ? ALTER Many help items fo ...
- js 条件语句控制html,如何避免在JS脚本上过多使用 if 语句?(技巧分享)
如何避免在JS脚本上过多使用 if 语句?本篇文章给大家分享一些方法来我们在 JS 中过多的使用 if 语句.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 最近在重构代码时,我发现 ...
- VS集成环境中的JavaScript脚本语法检查
集成在Visual Studio环境中的JavaScript脚本语法检查. 1.可以直接检验js文件,也可以检验html和aspx页面上的脚本语法. 2.集成环境中直接使用,双击定位到语法错误处. 3 ...
- php sqlserver开发实例,Linux_用sql脚本创建sqlserver数据库范例语句,下面是创建一个sqlserver数据库 - phpStudy...
用sql脚本创建sqlserver数据库范例语句 下面是创建一个sqlserver数据库的代码模板,加上一个创建表的模板.开发的时候可以拷贝过去直接改动一下就可以用了. 希望能帮上忙! 复制代码 代码 ...
- (P9)awk:什么是awk,awk简单用法,awk脚本语法,awk执行过程
文章目录 1.什么是awk 2.awk简单用法 3.awk脚本语法 4.awk执行过程 1.什么是awk awk 是什么 awk 是一种用于处理数据和生成报告的编程语言 awk 可以在命令行中进行一些 ...
最新文章
- 多目标跟踪 | FairMOT:统一检测、重识别的多目标跟踪框架,全新Baseline
- unity shader 编辑器扩展类 ShaderGUI
- 数据库PowerDesigner创建图表(模块表分类)
- matlab中文帮助_拿走不谢,simulink,stateflow,ecoder帮助手册中英对照版首发
- JAVA学习-JAVA实现一元二次方程求解
- 2021年前端还好找工作吗?
- 如何快速实现FaceTime多人视频效果
- Linux的巡检命令
- linux awk,sort,uniq,wc,cut命令详解
- 反应测试_SUPERCRC 微反应量热仪DARC差分加速量热仪 PT-DSC压力跟踪差示扫描量热仪...
- stm32气压传感器 带探头的_几种常用传感器
- UCDOS作者---鲍岳桥
- 在c语言中对于整型变量采用哪两种存储形式,在C语言中的实型变量分为2种类型,它们是()和()...
- C语言 商业贷款计算器 等额本金 等额本息
- Mapbox添加图片层
- 为什么要用RSocket
- PATA 1065 A+B and C (64bit) (20分)
- 结束进程导致桌面图标消失
- htc 8x android,htc 8x的usb驱动下载
- 【02】从零开始跟我一起制作一个鸿蒙的应用-★运行项目测试测试★---优雅草科技伊凡
热门文章
- uboot移植之迷雾解码
- Android开发仿微信支付宝的支付密码布局
- 中国成网络攻击最大受害国之一
- ZT世界第九大奇迹--北京西直门立交桥〔爆笑〕
- 豆果美食APP,看一下都给[Python爬虫爱好者]提供了哪些接口
- c盘瘦身。清理四个垃圾文件夹
- win10打开计算机出现马赛克,图片有马赛克怎么去除?win10给图片去除马赛克的方法...
- MTK FAQ最新资料,MTK_on_line_FAQ_SW_ALPS_Framework+-+Battery
- 大连到日本出差/旅游注意事项
- (2-分类问题)Accuracy,Precision,Sensitivity,Specificity