部分参考来源说明

Expect 手册中文版

Expect学习笔记

tcl英文手册

例子

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

expect命令

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

  • spawn用于启动一个进程

    -ignore选项用于忽略信号,例如: spawn –ignore SIGINT –ignore SIGHUP ping $host #就会屏蔽发送给ping进程的中断和挂起信号
  • expect用于匹配
  1. 用法1
  2. expect 表达式 {动作} 表达式 {动作} ...
  3. 用法2
  4. expect {
  5. 表达式 {动作}
  6. 表达式 {动作}
  7. ...
  8. }
  9. 两种用法是一样的,但是第二种用法格式比较清晰
  10. 使用expect_beforeexpect_after偷懒:
  11. 修改前:
  12. expect {
  13. "done" { puts "Done" }
  14. "p1" { puts "p1" }
  15. }
  16. expect {
  17. "done" { puts "Done" }
  18. "p2" { puts "p2" }
  19. }
  20. 修改后:
  21. expect_before done { puts "Done" }
  22. expect {
  23. "p1" { puts "p1" }
  24. }
  25. expect {
  26. "p2" { puts "p2" }
  27. }
  28. 如果上面第二个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是匹配程序输出的。
  1. expect_user {
  2. -re {[cC]hina} { puts stdout "中国" }
  3. -re {[jJ]apan} { puts stderr "日本" }
  4. }
  5. 上面的例子是如果用户输入china/China就打印"中国",输入japan/Japan就打印"日本"
  • exp_continue 是expect块中的动作,作用就是从块的开始部分重新匹配表达式
  • exp_internal 调试命令。
  1. exp_internal 0 关闭调试。
  2. exp_internal 1 开启调试,输出到标准输出中。
  3. exp_internal f file 0 调试信息写入文件,但不写到标准输出。
  4. exp_internal f file 1 调试信息写入文件,也写到标准输出。
  • exp_pid 这个命令用于获取spawned启动的进程的进程

    ID号,注意exp_id不是spawn_id。
  1. set pid0 [ exp_pid i $spawn_id ] #使用exp_pid获取spawned进程id,并赋值给pid0变量
  2. 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 命令用来将输出记录到一个文件中去,使用格式如下:
  1. log_file <选项> 文件名 当这个命令带有文件名时,表示将spawn程序的标准输出记录到文件中(我测试的结果是send_user的文本也进来了),只使用log_file命令但不带文件名则表示关闭记录。
  2. log_file的选项:
  3. -leaveopen 当文件已经被打开时,不继续向这个文件中添加内容。
  4. -noappend 如果文件已存在,那么清空文件中的内容,然后再写入。
  5. -a 如果文件已存在,则将新内容附加到当前文件的末尾。
  • log_user 命令,log_user 0 表示关闭spawn的所有输出,log_user 1表示spawn输出到标准输出。不太确定,还是贴上man手册
  1. log_user -info|0|1
  2. 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
  3. the logfile is unchanged.
  4. 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. 1-捕获到SIGINT HUP QUIT信号后,打印信号名和信号数值
  2. trap {
  3. send_user "signal name is [trap –name]\n" # -name选项用来显示信号名
  4. send_usersignal integer is [trap number]” # -number选项显示信号数值
  5. exit
  6. } {SIGINT SIGHUP SIGQUIT}
  7. 2-取消某些信号
  8. trap SIG_IGN { SIGINT SIGHUP SIGQUIT}
  9. 3-恢复信号的默认处理
  10. trap SIG_DFL { SIGINT SIGHUP SIGQUIT }
  • exit 退出命令,语法 exit [-opts] [status]。
  1. exit onexit {
  2. send_userGood bye\n
  3. }
  4. # -onexit选项后面可以跟onexit的handler,做扫尾工作。这些命令都可以man expect找到说明
  • interact 该命令是Expect中非常重要的命令之一,它用来在脚本中将控制权交给用户,由用户与spawn生成的进程进行交互。细节可以man expect
  1. 例子: # 输入完密码后,用户可以和远端shell交互,按q或ctrl+D将控制权重新还给脚本
  2. spawn ssh root@192.168.1.111
  3. interact {
  4. "q" {return}
  5. "\004" {return} # ascii 004是EOT 也就是ctrl+D
  6. }
  7. expect {
  8. ....
  9. }
  • interpreter 调用解释器,可以用于调试,比如puts变量内容。调试完后,可以使用return返回

expect命令的选项

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

    remove_nulls –d 1

    timeout –d 30 #设置默认超时
  • -i选项 一般用于同时控制多个spawn进程。
  1. 1.例如spawn好几个进程,每个spawn后面通过类似 set sp_id0 ${spwan_id}的命令 获取操作这个spawn进程的句柄。后面通过这个spawn id来控制,例如 exp_send -i ${sp_id0} "commmand1\r"
  2. 2.再例如,在expect的过程中使用spawn id才针对性匹配。比如:
  3. spawn ./hotpotcmd
  4. set hid ${spawn_id}
  5. spawn ./barbecure
  6. set bid ${spawn_id}
  7. expect {
  8. -i $hid
  9. -re {hot[pP]ot} { send_user "hotpot ok\n" }
  10. }
  11. expect {
  12. -i $bid
  13. -re {[bB]arbecure} { send_user "barbecure ok\n" }
  14. }
  • -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
  1. regexp {(cn|jp|kr) +([0-9]+) km} "cn 4022 km" all country num
  2. puts "all=$all country=$country num=$num"
  3. 回显: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 列表赋值
  1. lassign {a b c} x y z ;# Empty return
  2. puts $x ;# Prints "a"
  3. puts $y ;# Prints "b"
  4. puts $z ;# Prints "c"
  • linsert 列表插入,参考手册
  • lindex 列表取值(可以多个),参考手册
  • 其他列表操作: list, lappend, linsert, llength, lsearch, lset, lsort, lrange, lreplace, string 自己参考
  • dict 字典,
  • join 合并
  • expr 数学计算
  • if
  1. if {$vbl == 1} {
  2. puts "vbl is one"
  3. } elseif {$vbl == 2} {
  4. puts "vbl is two"
  5. } else {
  6. puts "vbl is not one or two"
  7. }
  • for和foreach
  1. for {set x 0} {$x<10} {incr x} {
  2. puts "x is $x"
  3. }
  4. set x {}
  5. foreach {i j} {a b c d e f} {
  6. lappend x $j $i
  7. }
  8. # The value of x is "b a d c f e"
  9. # There are 3 iterations of the loop.
  10. The next loop uses i and j to iterate over two lists in parallel.
  11. set x {}
  12. foreach i {a b c} j {d e f g} {
  13. lappend x $i $j
  14. }
  15. # The value of x is "a d b e c f {} g"
  16. # 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. Mysql到TiDB迁移,双写数据库兜底方案

    作者:京东零售 石磊 TiDB 作为开源 NewSQL 数据库的典型代表之一,同样支持 SQL,支持事务 ACID 特性.在通讯协议上,TiDB 选择与 MySQL 完全兼容,并尽可能兼容 MySQL ...

  2. c++基础之变量和基本类型

    之前我写过一系列的c/c++ 从汇编上解释它如何实现的博文.从汇编层面上看,确实c/c++的执行过程很清晰,甚至有的地方可以做相关优化.而c++有的地方就只是一个语法糖,或者说并没有转化到汇编中,而是 ...

  3. 【springboot整合druid】java.sql.SQLException: url not set

    问题描述 未使用自动装配的机制,实现springboot整合druid时(就是使用druid的jar包,而不是druid-spring-boot-starter)报错 <dependency&g ...

  4. Java 自增自减运算符和移位运算符介绍

    摘自 JavaGuide (「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识.准备 Java 面试,首选 JavaGuide!) 自增自减运算符 在写代码的过程中,常见的 ...

  5. VLE基于预训练文本和图像编码器的图像-文本多模态理解模型:支持视觉问答、图文匹配、图片分类、常识推理等

    VLE基于预训练文本和图像编码器的图像-文本多模态理解模型:支持视觉问答.图文匹配.图片分类.常识推理等 多模态预训练模型通过在多种模态的大规模数据上的预训练,可以综合利用来自不同模态的信息,执行各种 ...

  6. window hadoop yarn任务执行失败:ExitCodeException exitCode=-1073741515

    环境 window server 2019 单机版hadoop3.3.1 和 winutils.exe 异常 winutils.exe task create -m -1 -c -1 continer ...

  7. 顶配涨至近2万 该买还是买!iPhone15正面曝光 与历代苹果手机对比边框爆窄

    从曝光的iPhone 15正面渲染图来看,其颜值确实要比上代又提高不少. 外媒放出了一组iPhone 15 Pro的正面渲染图照,从图片看边框非常的窄,与历代iPhone 边框对比,这个特点更是被放大 ...

  8. Excel 分列功能 帮助 用户 导入Excel

    今天遇见一个客户的 Excel有一列 就是 导入不进去  那列 基本都是 数字 我试了下  写入几个字符 就能导入  不写字符的 就是导入 不进去 龚蓼 告诉我 用分列功能 今天试了下  草 果然可以 ...

  9. 《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(中)

    第 7 章 高级主题 7.2 并发 当两个用户获取同一个资源后,再同时修改该资源,就会导致并发问题 常见实现并发的方法有以下两种: 保守式并发控制,每次修改资源,都锁定资源 开放式并发控制,每次修改资 ...

  10. .NET Core开发实战(第3课:.NET Core的现状、未来以及环境搭建)--学习笔记

    03 | .NET Core的现状.未来以及环境搭建 .NET Core的现状 .NET Core 的应用场景:桌面端.Web端.云端.移动端.游戏.IOT 和 AI 云端指的是 .NET Core ...