TTL背景
所谓 TTL
, 其实是 Tera Term Language
的缩写, 也就是 Tera Term
的专用脚本语言. 那么 Tera Term(Wiki)是个什么东西呢? 其实就是个终端(Terminal), 也就是说跟什么 XSehll
, SecureCRT
, Putty
之类的东西差不多一个意思.
Tera Term 是日本人搞出来的东西. 其实仅仅就这个 Tera Term 来说我觉得一点并不好用, 完全比不上 Xshell
. 不过关键就在于它有它自己的脚本语言 Tera Term Language 啊. 有了自己的脚本语言加持以后, 这个终端瞬间化身自动化利器, 可以提前设计好各种操作, 剩下的就让终端自动运行好了.
Tera Term 这个东西本身我就不多介绍了, 只要到 Tera Term Open Source Project 下载安装即可. 写好的脚本双击以后是会自动调用这个工具的. 接下来的内容将会介绍 TTL
的语法和使用.
体验TTL
首先感受一下基本的 TTL
脚本可以干什么.
以下是参考官方例子写的一个最简单的 TTL 文件:
; A login sample by zhanglintc
; no timeout for keyword 'wait'
timeout = 0
; login infomation
hostname = 'your_hostname'
username = 'your_username'
password = 'your_password'
; login command
sprintf2 server '%s:22 /ssh /2 /auth=password /user=%s /passwd=%s' hostname username password
connect server
; hello world
wait '$' '#'
sendln 'echo hello world'
这个脚本可以使用设定好的 username
和 password
去连接 hostname
这台服务器. 连接上以后, 等待屏幕输出 $
或者 #
中的任意一个后(通常情况下这两个字符是 shell 的提示符, 出现这两个字符说明连接成功或者上一条命令成功了, 可以根据具体情况自行修改), 向远端发送命令 echo hello world
, 这里就相当于我们手动在命令行里输入了这条命令, 于是最终得到响应: hello world
.
[lane@vbox ~]$ echo hello world
hello world
TTL 脚本每行一个语句, 行尾不需要分号 ;
作为换行符. 因为分号 ;
之后的内容是注释, 此处语法高亮的灰色也表明了这一点. 其他一些关键字等将在后面陆续介绍.
TTL语法
注释:
; 分号开始的行是注释行
var = 0 ; 这里分号右边开开始也算注释
字面量:
; 支持正数负数, 不支持浮点数
123
-11
; $开始的数字是16进制
$3a
$10F
; 字符串
'Hello, world'
"I can't do that"
"汉字也支持"
; #开头的是ASCII码值字符, 也就是#后的数字查ASCII码表对应的是哪个字符就是哪个字符
#65 ; 文字 "A"
#$41 ; 文字 "A"
#13 ; CR 文字
; 字符串可以直接拼接
'cat readme.txt'#13#10 ; 相当于 "cat readme.txt\r\n"
'abc'#$0d#$0a'def'#$0d#$0a'ghi'
变量:
变量包括用户自定义变量和系统变量两部分.
下面将分别介绍一下.
自定义变量:
定义变量无需指定类型, 直接使用 变量名 = 值
的语法即可.
; 定义普通变量
_var = 'valid' ; 下划线开始的变量名合法
var_1 = 1 ; 这是一个数字
var_2 = 'str' ; 这是一个字符串
; 定义数组及赋值
intdim a 3 ; int数组
a[0] = 1
a[1] = 2
a[2] = 3
strdim s 3 ; str数组
s[0] = '1'
s[1] = '2'
s[2] = '3'
系统变量:
TTL 预置使用了一些系统变量, 写脚本的时候注意不要占用. 阅读脚本的时候要注意这些是系统变量, 是作为系统函数返回值而存在的.
常见的有 inputstr
, matchstr
, param1
... param9
, params
, result
, timeout
等.
具体请查看 Tera Term 的帮助文件.
inputstr ; waitln等函数的接收到的值存放于此
matchstr ; strmatch等函数的值存放于此
param1 ; 调用脚本时候传入的第一个参数
params ; 调用脚本时候传入的所有参数的数组
result ; waitln等函数执行的结果code存放于此
timeout ; 超时时间
流程控制:
TTL 也支持基本的流程控制操作.
do, loop
; 循环10次
i = 10
do while i > 0
i = i - 1
loop
while, endwhile
; 循环10次
i = 10
while i > 0
i = i - 1
endwhile
until, enduntil
; 循环10次
i = 1
until i > 10
i = i + 1
enduntil
for, next
; 循环10次
for i 1 10
sendln 'abc'
next
; 循环5次
for i 5 1
sendln 'abc'
next
if, then, elseif, else, endif
if a = 1 then
b = 1
c = 2
d = 3
endif
if i < 0 then
i = 0
else
i = i + 1
endif
if i = 1 then
c = '1'
elseif i = 2 then
c = '2'
elseif i = 3 then
c = '3'
else
c = '?'
endif
break, continue
; break
while 1
recvln
strcompare inputstr "OK"
if result = 0 then
break
else
sendln "abc..."
endif
endwhile
; continue
a = 0
b = 0
while a < 5
a = a + 1
if a > 2 then
continue
endif
b = b + 1
endwhile
sprintf2 var "a=%d b=%d" a b
dispstr var
; a=5 b=2
子过程
TTL 可以定义一些子过程, 方便重复调用. 但是没有返回值, 不能称之为函数.
定义子过程首先要了解 label 标签
; 冒号开始的是标签
: I_am_a_label ; 这就是一个标签
可以这样定义和调用子过程:
messagebox "I'm in main." "test"
; 跳转到":sub"
call sub
messagebox "Now I'm in main" "test"
end
; 子过程具体定义
:sub
messagebox "Now I'm in sub" "test"
return ; 返回到主体
典型用法
下面介绍一些 TTL 脚本中的常见写法.
连接服务器:
使用 connect
命令, 而且有不少其他命令必须在连接服务器后才能使用:
connect 'hostname:22 /ssh /2 /auth=password /user=username /passwd=password'
执行给定命令:
sendln 'date' ; 向远端服务器上发送 date 命令以及 CR, 即执行该命令
等待特定字符:
wait '$' '#' ; 等待远端服务器屏幕上出现 $ 或者 #. 未出现则一直等待. 该等待超时时间由系统变量 timeout 控制, 若为 0 则无超时时间, 即无限期等待
等待特定字符串并判断:
; 同时等待多个字符串, 匹配到任意一个进入下一步
wait 'condition1' 'condition2'
; 如果匹配到第一个, 系统变量 result 等于 1
; 匹配到第二个, 系统变量 result 等于 2, 以此类推
; 根据 result 的值进行条件分支
if result = 1 then
sendln 'echo match condition1'
else
sendln 'echo match condition2'
endif
拼接字符串:
- 使用
sprintf2
直接定义变量. 其中%s
是占位符, 被字符串后面跟的变量替换.hostname = 'your_hostname' username = 'your_username' password = 'your_password' sprintf2 server '%s:22 /ssh /2 /auth=password /user=%s /passwd=%s' hostname username password
- 直接声明变量并在后面添加字符串.
hostname = 'your_hostname' msg = hostname strconcat msg ':22 /ssh /2 /auth=password /user=' strconcat msg username strconcat msg ' /passwd=' strconcat msg password
保存服务器操作日志:
getdir logdir ; 获取当前脚本所在路径
changedir logdir ; 调整日志文件夹路径到当前路径
logfile = "operation.log" ; 日志文件名
logopen logfile 0 0 1 ; 打开日志文件用于写入
logwrite "first line in log file"#13#10 ; 向日志文件中写入"first line in log file\r\n", 其中 #13#10 的意思就是 CRLF