expect tcl 摘录
部分参考来源说明
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 摘录的更多相关文章
- 用expect做自动应答脚本
Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools).使用它系统管理员可以创 ...
- expect脚本远程登录、远程执行命令和脚本传参简单用法
expect介绍: 最近想写一个自动化安装脚本,涉及到远程登录.分发文件包.远程执行命令等,其中少不了来回输入登录密码,交互式输入命令等,这样就大大降低了效率,那么有什么方法能解决呢?不妨试试expe ...
- shell中expect免交互
expect前言观察ssh登录的交互现象有些程序难以避免的需要交互.你该如何解决脚本与程序的交互问题?名词解释期待, 预期, 盼望, 预料,料想, 指望, 希望, 要求,想, 认为一.概述 我们通过S ...
- 利用expect批量修改Linux服务器密码
一个执着于技术的公众号 背景 修改Linux系统密码,执行passwd即可更改密码.可如果有成千上百台服务器呢,通过ssh的方式逐一进行修改,对我们来说,工作量是非常大,且效率非常低下.因此采用批量修 ...
- postfix邮件服务器搭建01-准备篇
本系列文章主要介绍linux下主流的开源邮件系统postfix的搭建过程,构建一个通过postfix虚拟用户管理的完整的邮件系统, 该系统包括以下组件: 邮件收发端postfix,dovecot, 邮 ...
- linux tcl expect 安装(转)
linux tcl expect 安装 一.Tcl安装 1. 下载:tcl8.4.20-src.tar.gz http://www.tcl.tk/software/tcltk/downloadnow ...
- TCL/Expect交互式自动化测试概要 - - ITeye技术网站
TCL/Expect交互式自动化测试概要 - - ITeye技术网站 expect是一种基于TCL,能与交互式程序进行"可程序化"会话的脚本语言,是一种可以提供"分支和嵌 ...
- linux自动交互工具expect,tcl安装和安装包,以及自动互信脚本
linux自动交互工具expect,tcl安装,以及自动互信脚本 工作中需要对几十台服务器做自动互信,无意中发现expect命令,研究一番. 在网上找了许多资料也没有安装成功,摸索着总算成功了.现分享 ...
- 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 ...
- 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 ...
随机推荐
- 【AIGC】只要10秒,AI生成IP海报,解放双手!!!
看完这篇文章,你将学会以下价值连城的内容 1.云端部署(配置不行的小伙伴看)+ 云端模型放置位置 2.本地部署(配置达标的小伙伴看) 3.运用SD训练IP的流程和技巧(LoRA篇) 4.运用SD稳定生 ...
- Mac 版的 Quicker CirMenu
之前在Windows上用过一款圆盘菜单工具Quicker, 感觉非常方便, 换成Macos后,一直没有找到类似应用. 最近终于发现,一款好用的快捷键收集,触发工具CirMenu. 其核心功能是可以根据 ...
- .net Core IsDefined、GetValues、HasFlag 使用
IsDefined可以用于判断传入的单个值是否属于该枚举 GetValues检索指定枚举中常量值的数组 HasFlag 可以用于判断传入的多个值是否属于该枚举 先来个例子: public enum B ...
- ABP无法使用异步操作,但要调用异步方法
使用 AsyncHelper.RunSync(() => _studentRepository.FirstOrDefaultAsync(x => x.Code == studentCode ...
- 没有安装vs通过Rider编译Dll
没安装vs怎样生成dll? 比起VS那庞大的体积和编码效率,我还是更喜欢使用Rider(和VS的神级插件Resharper是同一家公司的产品),那么在没有安装VS的电脑上是否可以在命令行下把C#代码生 ...
- 开启想象翅膀:轻松实现文本生成模型的创作应用,支持LLaMA、ChatGLM、UDA、GPT2等模型,开箱即用
开启想象翅膀:轻松实现文本生成模型的创作应用,支持LLaMA.ChatGLM.UDA.GPT2等模型,开箱即用 1.介绍 TextGen实现了多种文本生成模型,包括:LLaMA.ChatGLM.UDA ...
- 关于Docker容器中的DNS配置
Docker: 1.启动时指定: docker run --dns 8.8.8.8 busybox:latest 2.全局配置: vi /etc/docker/daemon.json { " ...
- shell find 根据时间获取文件列表
根据时间得到文件,可以使用find进行查找,支持查找: find以时间为条件查找可用选项: -amin n:查找n分钟以前被访问过的所有文件. -atime n:查找n天以前被访问过的所有文件. -c ...
- Delphi 字符串截取函数【LeftStr,RightStr,MidStr】
如果要使用LeftStr,RightStr,MidStr必需引用系统单元StrUtils; 声明变量Str:string; Str:=HelloWorld; 1,LeftStr(Str,2)=He;/ ...
- .NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(下)
05 | 依赖注入:良好架构的起点 注册完毕之后,想替换某些组件的某些部分时,可以使用 Replace 和 RemoveAll services.AddSingleton<IOrderServi ...