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'

这个脚本可以使用设定好的 usernamepassword 去连接 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
Comments
Write a Comment