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 添加或删除元素
print 打印到标准输出或文件
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)相关推荐

  1. Lua脚本语法说明(修订)

    Lua脚本语法说明(增加lua5.1部份特性) Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了.估计看完了,就懂得 ...

  2. linux中的sh脚本语法

    linux中的sh脚本语法 玩linux都知道sh脚本的方便,但如何编写sh脚本却是像我这样的新手和菜鸟的难题.能不能编写得出来是一回事,了不了解又是另一回事.抱着好好学习,天天向上的精神,大家有空就 ...

  3. 2.5 Bro脚本入门

    基于Bro 2.5.3 文档,按照原文结构整理,非原文翻译,建议阅读英文文档后阅读,如有错误请不吝指出. 原文地址:https://www.bro.org/sphinx/scripting/index ...

  4. ubuntu中的fi语法_Shell脚本语法--if/then/elif/else/fi

    Shell脚本语法--if/then/elif/else/fi 和C语言类似,在Shell中用if.then.elif.else.fi这几条命令实现分支控制.这种流程控制语句本质上也是由若干条Shel ...

  5. GBase 8s SQL 指南:语法————2.2 SQL 语句

    ALTER ROUTINE 语句 使用 ALTER ROUTINE  语句更改先前定义的用户定义的例程(UDR)的例程修饰符或路径名.该 语句是 SQL ANSI/ISO  标准的扩展. 语法 元素 ...

  6. SQL语法基础之ALTER语句

    SQL语法基础之ALTER语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看ALTER的帮助信息 mysql> ? ALTER Many help items fo ...

  7. js 条件语句控制html,如何避免在JS脚本上过多使用 if 语句?(技巧分享)

    如何避免在JS脚本上过多使用 if 语句?本篇文章给大家分享一些方法来我们在 JS 中过多的使用 if 语句.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 最近在重构代码时,我发现 ...

  8. VS集成环境中的JavaScript脚本语法检查

    集成在Visual Studio环境中的JavaScript脚本语法检查. 1.可以直接检验js文件,也可以检验html和aspx页面上的脚本语法. 2.集成环境中直接使用,双击定位到语法错误处. 3 ...

  9. php sqlserver开发实例,Linux_用sql脚本创建sqlserver数据库范例语句,下面是创建一个sqlserver数据库 - phpStudy...

    用sql脚本创建sqlserver数据库范例语句 下面是创建一个sqlserver数据库的代码模板,加上一个创建表的模板.开发的时候可以拷贝过去直接改动一下就可以用了. 希望能帮上忙! 复制代码 代码 ...

  10. (P9)awk:什么是awk,awk简单用法,awk脚本语法,awk执行过程

    文章目录 1.什么是awk 2.awk简单用法 3.awk脚本语法 4.awk执行过程 1.什么是awk awk 是什么 awk 是一种用于处理数据和生成报告的编程语言 awk 可以在命令行中进行一些 ...

最新文章

  1. 多目标跟踪 | FairMOT:统一检测、重识别的多目标跟踪框架,全新Baseline
  2. unity shader 编辑器扩展类 ShaderGUI
  3. 数据库PowerDesigner创建图表(模块表分类)
  4. matlab中文帮助_拿走不谢,simulink,stateflow,ecoder帮助手册中英对照版首发
  5. JAVA学习-JAVA实现一元二次方程求解
  6. 2021年前端还好找工作吗?
  7. 如何快速实现FaceTime多人视频效果
  8. Linux的巡检命令
  9. linux awk,sort,uniq,wc,cut命令详解
  10. 反应测试_SUPERCRC 微反应量热仪DARC差分加速量热仪 PT-DSC压力跟踪差示扫描量热仪...
  11. stm32气压传感器 带探头的_几种常用传感器
  12. UCDOS作者---鲍岳桥
  13. 在c语言中对于整型变量采用哪两种存储形式,在C语言中的实型变量分为2种类型,它们是()和()...
  14. C语言 商业贷款计算器 等额本金 等额本息
  15. Mapbox添加图片层
  16. 为什么要用RSocket
  17. PATA 1065 A+B and C (64bit) (20分)
  18. 结束进程导致桌面图标消失
  19. htc 8x android,htc 8x的usb驱动下载
  20. 【02】从零开始跟我一起制作一个鸿蒙的应用-★运行项目测试测试★---优雅草科技伊凡

热门文章

  1. uboot移植之迷雾解码
  2. Android开发仿微信支付宝的支付密码布局
  3. 中国成网络攻击最大受害国之一
  4. ZT世界第九大奇迹--北京西直门立交桥〔爆笑〕
  5. 豆果美食APP,看一下都给[Python爬虫爱好者]提供了哪些接口
  6. c盘瘦身。清理四个垃圾文件夹
  7. win10打开计算机出现马赛克,图片有马赛克怎么去除?win10给图片去除马赛克的方法...
  8. MTK FAQ最新资料,MTK_on_line_FAQ_SW_ALPS_Framework+-+Battery
  9. 大连到日本出差/旅游注意事项
  10. (2-分类问题)Accuracy,Precision,Sensitivity,Specificity