部分参考来源说明

Expect 手册中文版

Expect学习笔记

tcl英文手册

例子

#!/usr/bin/expect
# ssh
# send_user -- 用来避免后面出现以-开头的用户提示信息被解释成非法参数
#send_user -- "---------------------------------\n"
if { $argc < 4 } {
send_user " ERROR : Invalid arguments.\n"
send_user " Usage : $argv0 host user pw cmd\n"
exit 10
} set host [ lindex $argv 0 ]
set user [ lindex $argv 1 ]
set pw [ lindex $argv 2 ]
set cmd [ lindex $argv 3 ]
set timemout 15 spawn ssh $user@$host $cmd
# 获取spawn_id
set ssh_id $spawn_id # Note : exp_internal要位于spawn后, 0表示关闭调试模式,非0表示开启调试模式 , -f file表示调试内容写入文件。
# 组合使用时: exp_internal -f file 0 ,后面的0表示调试信息仅仅写到文件,如果后面是1则调试信息写入文件同时输出到stdout
exp_internal -f /tmp/exp_exec.log 0 expect {
-nocase "yes/no" {
exp_send "yes\r"
# Notice : exp_continue必须处于expect内,它能让expect再次从第一次匹配
exp_continue
}
-nocase "password:" {
exp_send "${pw}\r"
expect "try again" {
send_user "\nERROR: Password is incrrect!\n"
# close不带参数时默认关闭当前spawn_id
close $ssh_id
exit 12
}
} # Note: default 包含了timeout和eof
default {
send_error "ERROR : timeout or eof.\n"
close $ssh_id
exit 11
}
}

expect命令

核心命令有三个 spawn、expect、send

  • spawn用于启动一个进程

    -ignore选项用于忽略信号,例如: spawn –ignore SIGINT –ignore SIGHUP ping $host #就会屏蔽发送给ping进程的中断和挂起信号
  • expect用于匹配
    用法1:
expect 表达式 {动作} 表达式 {动作} ...
用法2:
expect {
表达式 {动作}
表达式 {动作}
...
} 两种用法是一样的,但是第二种用法格式比较清晰 使用expect_before或expect_after偷懒:
修改前:
expect {
"done" { puts "Done" }
"p1" { puts "p1" }
}
expect {
"done" { puts "Done" }
"p2" { puts "p2" }
}
修改后:
expect_before “done” { puts "Done" }
expect {
"p1" { puts "p1" }
}
expect {
"p2" { puts "p2" }
}
如果上面第二个expect块后面还有expect_before,则后面的expect_before会覆盖前面的expect_before。当然如果上面每个expect块中都有"done"表达式,那么块内的优先级会比expect_before的要高
  • send 用来发动作的,也可以使用exp_send命令(exp_send是send的别名)。 exp_send有两个选项:-i和-s,选项具体含义看后面说明。支持八进制和十六进制发送,比如exp_send "\r" 可以写成 exp_send "\015"或exp_send "\x0d"

其他expect命令

  • expect_user匹配用户输入,而前面的expect是匹配程序输出的。
    expect_user {
-re {[cC]hina} { puts stdout "中国" }
-re {[jJ]apan} { puts stderr "日本" }
}
上面的例子是如果用户输入china/China就打印"中国",输入japan/Japan就打印"日本"
  • exp_continue 是expect块中的动作,作用就是从块的开始部分重新匹配表达式
  • exp_internal 调试命令。
    exp_internal  0      关闭调试。
exp_internal 1 开启调试,输出到标准输出中。
exp_internal –f file 0 调试信息写入文件,但不写到标准输出。
exp_internal –f file 1 调试信息写入文件,也写到标准输出。
  • exp_pid 这个命令用于获取spawned启动的进程的进程

    ID号,注意exp_id不是spawn_id。
    set pid0 [ exp_pid –i $spawn_id ]  #使用exp_pid获取spawned进程id,并赋值给pid0变量
send_user "spawned进程的pid是[ exp_pid –i $spawn_id ]\n" #打印spawned进程的id
  • send_user 相对于send,exp_send发送数据给进程,send_user是发送数据给标准输出。send_error是类似的命令,只不过输出到标准错误
  • send_log 命令输出到日志文件中。需要配合log_file命令使用
  • log_file 命令用来将输出记录到一个文件中去,使用格式如下:
    log_file  <选项>  文件名 当这个命令带有文件名时,表示将spawn程序的标准输出记录到文件中(我测试的结果是send_user的文本也进来了),只使用log_file命令但不带文件名则表示关闭记录。

    log_file的选项:
-leaveopen 当文件已经被打开时,不继续向这个文件中添加内容。
-noappend 如果文件已存在,那么清空文件中的内容,然后再写入。
-a 如果文件已存在,则将新内容附加到当前文件的末尾。
  • log_user 命令,log_user 0 表示关闭spawn的所有输出,log_user 1表示spawn输出到标准输出。不太确定,还是贴上man手册
    log_user -info|0|1
By default, the send/expect dialogue is logged to stdout (and a logfile if open). The logging to stdout is disabled by the command "log_user 0" and reenabled by "log_user 1". Logging to
the logfile is unchanged. The -info flag causes log_user to return a description of the most recent non-info arguments given.
  • 总结一下上面的输出:主动使用send_user或send_error的输出,主动使用send_log写文件的输出。还有使用log_user控制spawn send/expect是否输出到标准输出

  • close close命令用来关闭连接,它支持-i选项,用来关闭指定句柄的过程,如果不带任何选项,则关闭当前$spawn_id变量指定的过程。

  • wait wait命令与close命令相似,都是用来关闭连接的,但wait命令是等待系统主动返回eof,也就是结束信号后才关闭,而不是像close那样无条件关闭,与close命令一样,它也支持-i选项。

  • remove_nulls expect中,默认会去掉返回中的控制符,注意:不要将控制符与空白符搞混,控制符主要是信号,他们是不会显示在屏幕上的,比如使用ctrl+c(中断)、ctrl+d(终止)等组合键发送的信号,信号是ASCII码表中01-31区间中的字符;空白符则是可以显示出来的空白符号,比如空格、回车、换行、制表等一系列符号。

    remove_nulls命令可以控制是否去掉返回中的控制符,使用方法如下:

    remove_nulls 0 #关闭自动去掉控制符的功能

    remove_nulls 1 #开始知道去掉控制符的功能,这是默认值。

  • match_max 用来设置expect_out(buffer)变量的缓存大小,默认情况下expect_out(buffer)变量缓存是2000个字符,你可以设置这个大小来设置更符合实际的缓存,使用方法如下:match_max 65535 支持-i或-d选项,-i和-d见本文的选项介绍

  • trap 信号处理,语法是 trap [[command] signal], 例如expect默认有:trap exit

    1-捕获到SIGINT HUP QUIT信号后,打印信号名和信号数值
trap {
send_user "signal name is [trap –name]\n" # -name选项用来显示信号名
send_user“signal integer is [trap –number]” # -number选项显示信号数值
exit
} {SIGINT SIGHUP SIGQUIT} 2-取消某些信号
trap SIG_IGN { SIGINT SIGHUP SIGQUIT} 3-恢复信号的默认处理
trap SIG_DFL { SIGINT SIGHUP SIGQUIT }
  • exit 退出命令,语法 exit [-opts] [status]。
    exit –onexit {
send_user“Good bye\n”
}
# -onexit选项后面可以跟onexit的handler,做扫尾工作。这些命令都可以man expect找到说明
  • interact 该命令是Expect中非常重要的命令之一,它用来在脚本中将控制权交给用户,由用户与spawn生成的进程进行交互。细节可以man expect
     例子:  # 输入完密码后,用户可以和远端shell交互,按q或ctrl+D将控制权重新还给脚本
spawn ssh root@192.168.1.111
interact {
"q" {return}
"\004" {return} # ascii 004是EOT 也就是ctrl+D
} expect {
....
}
  • interpreter 调用解释器,可以用于调试,比如puts变量内容。调试完后,可以使用return返回

expect命令的选项

  • -d选项 几乎所有expect命令都支持-d选项,d代表default,也就是设置某些命令的默认值,比如:

    remove_nulls –d 1

    timeout –d 30 #设置默认超时
  • -i选项 一般用于同时控制多个spawn进程。
  1.例如spawn好几个进程,每个spawn后面通过类似 set sp_id0 ${spwan_id}的命令 获取操作这个spawn进程的句柄。后面通过这个spawn id来控制,例如 exp_send -i ${sp_id0} "commmand1\r"
2.再例如,在expect的过程中使用spawn id才针对性匹配。比如:
spawn ./hotpotcmd
set hid ${spawn_id}
spawn ./barbecure
set bid ${spawn_id}
expect {
-i $hid
-re {hot[pP]ot} { send_user "hotpot ok\n" }
}
expect {
-i $bid
-re {[bB]arbecure} { send_user "barbecure ok\n" }
}
  • -f选项,f代表 file ,某些Expect命令支持这个选项,比如exp_internal命令,这个选项用来将某些命令的输出放入一个文件中去,因此这个选项后面必须带有文件的路径作为值。
  • -s选项

    s代表slowly,也就是发送速度,这个选项一般用于send族命令中,比如send、exp_send、send_user、send_error等等,使用这个选项之前,必须先对send_slow变量赋值,send_slow变量设置expect发送字符的速度,它接受2个参数,一个是字符个数,另一个是时间,使用方法如下:

    set send_slow {character seconds}

    第一个参数是字符个数,第二个是时间,单位为秒,比如:set send_slow {10 1} 表示每秒钟发送10个字符,当然如果生效,send命令必须加上-s参数,比如:set send_slow {10 1}; send -s “hello\r”
  • -h选项 代表human,用来模拟人敲击键盘的动作,可以用于所有send命令族,比如exp_send、send_user等等,使用之前必须先对send_human变量赋值。例如:set send_human {.1 .5 1 .05 2} 四个参数分别表示:.1每个字母输入的平均间隔(0.1秒).5表示单词输入完后停顿时间。1表示间隔时间变化的剧烈程度,取值0到无穷大,1表示比较合理的,需要结合最后两个参数。.05表示输入字符最小间隔时间,2表示输入字符最大间隔时间。
  • -gl选项,代表global,用于指定全局类型的表达式,用于expect、interact命令族中,比如expect、expect_user、expect_error等,global形式的表达式与DOS的通配符相似,用*表示任意多个任意字符,?表示一个任意字符,这是一种很简单的表达式
  • -ex选项,代表exact,用于指定精确类型的表达式,用于expect、interact命令族中,这种类型的表达式特点就是所有字符都精确代表它本身的含义,不存在通配符。
  • -re选项代表regular expression,也就是正则表达式,用于expect、interact命令族中
  • -null选项,这个选项可以用于expect和send过程,用于expect时表示连同空字符也一样做匹配(默认情况下不匹配),用于send则用于发送空字符,在send命令中还可以一次发送多个空字符,比如:send –null 3
  • -ignore选项,这个选项用于spawn命令,用来忽略某些特殊的信号,比如忽略ctrl+c和ctrl+d:spawn–ignore SIGINT –ignore SIGHUP ping $host
  • -info选项用于expect_before和expect_after命令中,用于对这两个命令的调试
  • -onexit见上面的exit命令,-number和-name选项见trap命令,这里省略
  • --选项,表示选项的终止

变量

  • expect_out(buffer),数组,这个变量中放置从上一次匹配到这一次匹配之间的所有返回,包括匹配字符本身。
  • spawn_id 专门用于expect中的进程管理

tcl摘录

数据类型

  • tcl只有一种数据类型--字符串

符号

  • $ 变量展开(substitution). $var或${var}是标量变量展开,$var(index)是数组变量展开
  • [] 方括号,命令展开,也就是执行括号内的命令,例如set kernel [ exec bash -c {uname -r} ] # kernel的值为内核版本号
  • " 双引号把词组标记为命令的一个参数. 注意:"$"符号和方括号在双引号内仍被expect解释
  • { } 大括号也把词组标记为命令的一个参数. 但是, 其他符号在大括号内不被解释(保持原样)
  • \ 反斜线\表示转义,支持八进制、16进制、unicode: \ooo \xhh \uhhhh

命令

  • 参考 http://www.tcl-lang.org/man/tcl8.6/TclCmd/contents.htm,下面只摘录部分
  • set 用于变量赋值,unset用于清除变量。 例如set var "xxxx" #普通变量; set week(mon) 1 #赋值数组; set d [expr 10+15]
  • expr
  • format 类似于c的sprintf。例如 set var [ format "year=%s mon=%s" $year $mon]
  • scan 类似c的sscanf。例如 scan "some 26 34" "some %d %d" a b
  • regexp 正则匹配。语法 regexp [switchs] [--] expr_string [matchVar] [submatchVar] [submatchVar]...

    switch支持 -nocase -line
    regexp {(cn|jp|kr) +([0-9]+) km} "cn 4022 km" all country num
puts "all=$all country=$country num=$num"
回显:all=cn 4022 km country=cn num=4022
  • append 追加到变量,例如 set var "af"; append var ":01" ":b3" #则var值为"af:01:b3"
  • lappend — Append list elements onto a variable
  • lassign 列表赋值
    lassign {a b c} x y z       ;# Empty return
puts $x ;# Prints "a"
puts $y ;# Prints "b"
puts $z ;# Prints "c"
  • linsert 列表插入,参考手册
  • lindex 列表取值(可以多个),参考手册
  • 其他列表操作: list, lappend, linsert, llength, lsearch, lset, lsort, lrange, lreplace, string 自己参考
  • dict 字典,
  • join 合并
  • expr 数学计算
  • if
    if {$vbl == 1} {
puts "vbl is one"
} elseif {$vbl == 2} {
puts "vbl is two"
} else {
puts "vbl is not one or two"
}
  • for和foreach
    for {set x 0} {$x<10} {incr x} {
puts "x is $x"
} set x {}
foreach {i j} {a b c d e f} {
lappend x $j $i
}
# The value of x is "b a d c f e"
# There are 3 iterations of the loop.
The next loop uses i and j to iterate over two lists in parallel. set x {}
foreach i {a b c} j {d e f g} {
lappend x $i $j
}
# The value of x is "a d b e c f {} g"
# There are 4 iterations of the loop.

其他说明

  • log_user 命令用来指定Expect输出的位置,默认情况下log_user的值是1,表示所有输出都放在标准输出中(一般是显示器,如果采用重定向也可以定位到文件中),如果将这个值赋值为0就表示不需要任何输出。

  • log_file 命令用来将输出记录到一个文件中去,使用格式如下:

    log_file <选项> 文件名

    选项包括下面几种:

    -open当一个文件已经被打开时,使用这个选项可以往这个文件里继续添加内容,这个选项一般用于windows系统,因为windows系统中文件是独占的,Linux系统中就不存在这个问题了。

    -leaveopen当文件已经被打开时,不继续向这个文件中添加内容。

    -noappend如果文件已存在,那么清空文件中的内容,然后再写入。

    -a如果文件已存在,则将新内容附加到当前文件的末尾。当这个命令带有文件名时,表示将spawn程序的标准输出记录到文件中,只使用log_file命令但不带文件名则表示关闭记录,这样你就可以只记录自己感兴趣的部分了。

  • remove_nulls

    expect中,默认会去掉返回中的控制符,注意:不要将控制符与空白符搞混,控制符主要是信号,他们是不会显示在屏幕上的,比如使用ctrl+c(中断)、ctrl+d(终止)等组合键发送的信号,信号是ASCII码表中01-31区间中的字符;空白符则是可以显示出来的空白符号,比如空格、回车、换行、制表等一系列符号。

    remove_nulls命令可以控制是否去掉返回中的控制符,使用方法如下:

    remove_nulls0# 关闭自动去掉控制符的功能

    remove_nulls1# 开启自动去掉控制符的功能,这是默认值

  • 含有””(和-re “.”)的模糊匹配的模式会清空输出缓冲区,不再读取从进程中输出的字符。更多关于输出缓冲区的说明

expect tcl 摘录的更多相关文章

  1. 用expect做自动应答脚本

    Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools).使用它系统管理员可以创 ...

  2. expect脚本远程登录、远程执行命令和脚本传参简单用法

    expect介绍: 最近想写一个自动化安装脚本,涉及到远程登录.分发文件包.远程执行命令等,其中少不了来回输入登录密码,交互式输入命令等,这样就大大降低了效率,那么有什么方法能解决呢?不妨试试expe ...

  3. shell中expect免交互

    expect前言观察ssh登录的交互现象有些程序难以避免的需要交互.你该如何解决脚本与程序的交互问题?名词解释期待, 预期, 盼望, 预料,料想, 指望, 希望, 要求,想, 认为一.概述 我们通过S ...

  4. 利用expect批量修改Linux服务器密码

    一个执着于技术的公众号 背景 修改Linux系统密码,执行passwd即可更改密码.可如果有成千上百台服务器呢,通过ssh的方式逐一进行修改,对我们来说,工作量是非常大,且效率非常低下.因此采用批量修 ...

  5. postfix邮件服务器搭建01-准备篇

    本系列文章主要介绍linux下主流的开源邮件系统postfix的搭建过程,构建一个通过postfix虚拟用户管理的完整的邮件系统, 该系统包括以下组件: 邮件收发端postfix,dovecot, 邮 ...

  6. linux tcl expect 安装(转)

    linux tcl expect 安装 一.Tcl安装 1.  下载:tcl8.4.20-src.tar.gz http://www.tcl.tk/software/tcltk/downloadnow ...

  7. TCL/Expect交互式自动化测试概要 - - ITeye技术网站

    TCL/Expect交互式自动化测试概要 - - ITeye技术网站 expect是一种基于TCL,能与交互式程序进行"可程序化"会话的脚本语言,是一种可以提供"分支和嵌 ...

  8. linux自动交互工具expect,tcl安装和安装包,以及自动互信脚本

    linux自动交互工具expect,tcl安装,以及自动互信脚本 工作中需要对几十台服务器做自动互信,无意中发现expect命令,研究一番. 在网上找了许多资料也没有安装成功,摸索着总算成功了.现分享 ...

  9. Linux Tcl和Expect的安装

    一.先安装Tcl 1.下载:tcl版本 8.4.19 http://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz ...

  10. linux上安装tcl、tk、expect

    linux上安装tcl.tk.expect   1.tcl安装tcl8.5.9-src.tar.gz cd /tmp tar -zxvf tcl8.5.9-src.tar.gz cd tcl8.5.9 ...

随机推荐

  1. Promise.all()方方详解

    1.Promise.all()方方详解 Promise.all,只有所有的Promise成功,才能够算作成功,只要有一个失败了,就直接失败: 它包含一个参数,这个参数是指包含多个Promise的数组: ...

  2. PostgreSQL中的B-TREE索引

    分析了解pgsql中的索引 前言 索引 B-tree B-Tree和B+Tree的区别: pgsql中B-Tree 实现 如果该节点不是最右节点 如果该节点是最右节点 参考 分析了解pgsql中的索引 ...

  3. 解决Edge浏览器提示“此网站已被人举报不安全”

    今天下午微软旗下的 Microsoft Edge 浏览器将百度搜索的跳转域名 (*.baidu.com/link?url=*) 封杀,百度搜索首页可以打开,但搜索任何关键词点击搜索结果都会被拦截. 当 ...

  4. 使用CAShapeLayer,UIBezierPath,CAGradientLayer构建边框颜色会旋转的六边形

    主要思路是: 1.使用UIBezierPath绘制一个六边形路径 2.创建一个CAShapeLayer图层,将这个六边形path设置到CAShapeLayer属性上.然后设置fillColor为透明, ...

  5. P5309 [Ynoi2011] 初始化 题解

    题目链接:初始化 这种 ynoi 的老题就是卡常.来简单说说这题的思维切入口. 看到形如 \(y+k \times x\) 的结构,自然而然思考一下如果我们是暴力更新会有怎么样的效果.我们容易发现,如 ...

  6. ElasticSearch7.3学习(三)----采用restful风格 批量(bulk)增删改

    Bulk 操作是将文档的增删改查一些列操作,通过一次请求全都做完.目的是减少网络传输次数. 语法: POST /_bulk {"action": {"metadata&q ...

  7. Python 元组详细使用

    1. 元组 元组和列表类似,但属于不可变序列,元组一旦创建,用任何方法都不可修改其元素. 元组的定义方式和列表相同,但定义时所有元素是放在一对圆括号"()"中,而不是方括号中. 1 ...

  8. Hbase简单介绍

    一.背景介绍 我们生活在一个互联网的时代,这个时代的特点是,无论任何事情,只要我们想知道,都可以通过互联网迅速的检索到问题的答案,并且答案是有用的,并非常切合我们的需要. 因此,很多公司都开始致力于提 ...

  9. Oracle查询存在外键约束但未创建对应索引的情况

    1.Oracle提供的脚本 2.网络搜索到的脚本 3.改为可以指定用户的脚本 4.测试脚本使用 1.Oracle提供的脚本 如果要求管控严格,可以考虑使用Oracle官方提供的脚本. Script t ...

  10. 《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(上)

    第 8 章 认证和安全 8.1 认证 认证(Authentication)是指验证用户身份的过程,授权(Authorization)是验证一个已经通过认证的用户是否有权限做某些事的过程 常见的 HTT ...